You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@deltaspike.apache.org by st...@apache.org on 2012/04/15 20:41:59 UTC

[2/3] DELTASPIKE-129 move AnnotationBuilder and stuff to util package

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/78d0434e/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/metadata/builder/InjectableMethod.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/metadata/builder/InjectableMethod.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/metadata/builder/InjectableMethod.java
deleted file mode 100644
index b3cfc2d..0000000
--- a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/metadata/builder/InjectableMethod.java
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * 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.apache.deltaspike.core.api.metadata.builder;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-import javax.enterprise.context.spi.CreationalContext;
-import javax.enterprise.inject.spi.AnnotatedMethod;
-import javax.enterprise.inject.spi.Bean;
-import javax.enterprise.inject.spi.BeanManager;
-import javax.enterprise.inject.spi.InjectionPoint;
-
-import org.apache.deltaspike.core.api.metadata.builder.ParameterValueRedefiner.ParameterValue;
-
-import static org.apache.deltaspike.core.util.BeanUtils.createInjectionPoints;
-import static org.apache.deltaspike.core.util.ReflectionUtils.invokeMethod;
-
-/**
- * <p>
- * Allows an {@link AnnotatedMethod} to be injected using the CDI type safe
- * resolution rules.
- * </p>
- * <p/>
- * <p>
- * {@link ParameterValueRedefiner} allows the default value to be overridden by
- * the caller of
- * {@link #invoke(Object, CreationalContext, ParameterValueRedefiner)}.
- * </p>
- *
- * @param <X> the declaring type
- */
-public class InjectableMethod<X>
-{
-    private final AnnotatedMethod<X> method;
-    private final List<InjectionPoint> parameters;
-    private final BeanManager beanManager;
-
-    /**
-     * Instantiate a new {@link InjectableMethod}.
-     *
-     * @param method        the method which will be injected upon a call to
-     *                      {@link #invoke(Object, CreationalContext)}
-     * @param declaringBean the bean which defines the injectable method
-     * @param beanManager   the {@link BeanManager} to use to obtain the parameter values
-     */
-    public InjectableMethod(AnnotatedMethod<X> method, Bean<?> declaringBean, BeanManager beanManager)
-    {
-        this(method, createInjectionPoints(method, declaringBean, beanManager), beanManager);
-    }
-
-    /**
-     * Instantiate a new {@link InjectableMethod}.
-     *
-     * @param method      the method which will be injected upon a call to
-     *                    {@link #invoke(Object, CreationalContext)}
-     * @param parameters  a collection of injection points representing the
-     *                    parameters of the method
-     * @param beanManager the {@link BeanManager} to use to obtain the parameter
-     *                    values
-     */
-    public InjectableMethod(AnnotatedMethod<X> method, Collection<InjectionPoint> parameters, BeanManager beanManager)
-    {
-        this.method = method;
-        this.parameters = new ArrayList<InjectionPoint>(parameters);
-        this.beanManager = beanManager;
-    }
-
-    /**
-     * Get the bean manager used by this injectable method.
-     *
-     * @return the bean manager in use
-     */
-    protected BeanManager getBeanManager()
-    {
-        return beanManager;
-    }
-
-    /**
-     * Get the injectable parameters of this method.
-     *
-     * @return a collection of injection points representing the parameters of
-     *         this method
-     */
-    protected List<InjectionPoint> getParameters()
-    {
-        return parameters;
-    }
-
-    /**
-     * Invoke the method, causing all parameters to be injected according to the
-     * CDI type safe resolution rules.public class ParameterValueRedefiner {
-     * <p/>
-     * }
-     *
-     * @param <T>               the return type of the method
-     * @param receiver          the instance upon which to call the method
-     * @param creationalContext the creational context to use to obtain
-     *                          injectable references for each parameter
-     * @return the result of invoking the method or null if the method's return
-     *         type is void
-     * @throws RuntimeException            if this <code>Method</code> object enforces Java
-     *                                     language access control and the underlying method is
-     *                                     inaccessible or if the underlying method throws an exception or
-     *                                     if the initialization provoked by this method fails.
-     * @throws IllegalArgumentException    if the method is an instance method and
-     *                                     the specified <code>receiver</code> argument is not an instance
-     *                                     of the class or interface declaring the underlying method (or
-     *                                     of a subclass or implementor thereof); if an unwrapping
-     *                                     conversion for primitive arguments fails; or if, after possible
-     *                                     unwrapping, a parameter value cannot be converted to the
-     *                                     corresponding formal parameter type by a method invocation
-     *                                     conversion.
-     * @throws NullPointerException        if the specified <code>receiver</code> is
-     *                                     null and the method is an instance method.
-     * @throws ExceptionInInitializerError if the initialization provoked by this
-     *                                     method fails.
-     */
-    public <T> T invoke(Object receiver, CreationalContext<T> creationalContext)
-    {
-        return invoke(receiver, creationalContext, null);
-    }
-
-    /**
-     * Invoke the method, calling the parameter redefiner for each parameter,
-     * allowing the caller to override the default value obtained via the CDI
-     * type safe resolver.
-     *
-     * @param <T>               the return type of the method
-     * @param receiver          the instance upon which to call the method
-     * @param creationalContext the creational context to use to obtain
-     *                          injectable references for each parameter
-     * @return the result of invoking the method or null if the method's return
-     *         type is void
-     * @throws RuntimeException            if this <code>Method</code> object enforces Java
-     *                                     language access control and the underlying method is
-     *                                     inaccessible or if the underlying method throws an exception or
-     *                                     if the initialization provoked by this method fails.
-     * @throws IllegalArgumentException    if the method is an instance method and
-     *                                     the specified <code>receiver</code> argument is not an instance
-     *                                     of the class or interface declaring the underlying method (or
-     *                                     of a subclass or implementor thereof); if an unwrapping
-     *                                     conversion for primitive arguments fails; or if, after possible
-     *                                     unwrapping, a parameter value cannot be converted to the
-     *                                     corresponding formal parameter type by a method invocation
-     *                                     conversion.
-     * @throws NullPointerException        if the specified <code>receiver</code> is
-     *                                     null and the method is an instance method.
-     * @throws ExceptionInInitializerError if the initialization provoked by this
-     *                                     method fails.
-     */
-    public <T> T invoke(Object receiver, CreationalContext<T> creationalContext, ParameterValueRedefiner redefinition)
-    {
-        List<Object> parameterValues = new ArrayList<Object>();
-        for (int i = 0; i < getParameters().size(); i++)
-        {
-            if (redefinition != null)
-            {
-                ParameterValue value = new ParameterValue(i, getParameters().get(i), getBeanManager());
-                parameterValues.add(redefinition.redefineParameterValue(value));
-            }
-            else
-            {
-                parameterValues.add(getBeanManager().getInjectableReference(getParameters().get(i), creationalContext));
-            }
-        }
-
-        try
-        {
-            @SuppressWarnings({ "unchecked", "UnnecessaryLocalVariable" })
-            T result =
-                    (T) invokeMethod(receiver, method.getJavaMember(), Object.class, true, parameterValues.toArray());
-            return result;
-        }
-        catch (RuntimeException e)
-        {
-            //X TODO check if it is compatible with Weld
-            //workaround for OWB which wraps InvocationTargetException the original exception
-            //see ReflectionUtils#invokeMethod
-            if (RuntimeException.class.getName().equals(e.getClass().getName()) &&
-                    e.getCause() instanceof RuntimeException)
-            {
-                throw (RuntimeException)e.getCause();
-            }
-            throw e;
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/78d0434e/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/metadata/builder/ParameterValueRedefiner.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/metadata/builder/ParameterValueRedefiner.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/metadata/builder/ParameterValueRedefiner.java
deleted file mode 100644
index 3351b49..0000000
--- a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/metadata/builder/ParameterValueRedefiner.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * 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.apache.deltaspike.core.api.metadata.builder;
-
-import javax.enterprise.context.spi.CreationalContext;
-import javax.enterprise.inject.spi.BeanManager;
-import javax.enterprise.inject.spi.InjectionPoint;
-
-/**
- * Provides the ability to redefine the value of a parameter on an
- * {@link InjectableMethod} via the
- * {@link #redefineParameterValue(ParameterValue)} callback.
- *
- * @see InjectableMethod
- */
-public interface ParameterValueRedefiner
-{
-    /**
-     * Callback allowing the default parameter value (that which would be
-     * injected according to the CDI type safe resolution rules) to be
-     * overridden.
-     *
-     * @param value the default value
-     * @return the overridden value
-     */
-    Object redefineParameterValue(ParameterValue value);
-
-    /**
-     * Provides the default parameter's value, along with metadata about the
-     * parameter to a parameter redefinition.
-     *
-     * @see ParameterValueRedefiner
-     * @see InjectableMethod
-     */
-    public static class ParameterValue
-    {
-
-        private final int position;
-        private final InjectionPoint injectionPoint;
-        private final BeanManager beanManager;
-
-        ParameterValue(int position, InjectionPoint injectionPoint, BeanManager beanManager)
-        {
-            this.position = position;
-            this.injectionPoint = injectionPoint;
-            this.beanManager = beanManager;
-        }
-
-        /**
-         * Get the position of the parameter in the member's parameter list.
-         *
-         * @return the position of the parameter
-         */
-        public int getPosition()
-        {
-            return position;
-        }
-
-        /**
-         * Get the {@link InjectionPoint} for the parameter.
-         *
-         * @return the injection point
-         */
-        public InjectionPoint getInjectionPoint()
-        {
-            return injectionPoint;
-        }
-
-        /**
-         * Get the default value of the parameter. The default value is that which
-         * would be injected according to the CDI type safe resolution rules.
-         *
-         * @param creationalContext the creationalContext to use to obtain the
-         *                          injectable reference.
-         * @return the default value
-         */
-        public Object getDefaultValue(CreationalContext<?> creationalContext)
-        {
-            return beanManager.getInjectableReference(injectionPoint, creationalContext);
-        }
-
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/78d0434e/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/BeanUtils.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/BeanUtils.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/BeanUtils.java
index bcc3890..b890b43 100644
--- a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/BeanUtils.java
+++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/BeanUtils.java
@@ -18,7 +18,7 @@
  */
 package org.apache.deltaspike.core.util;
 
-import org.apache.deltaspike.core.api.metadata.builder.ImmutableInjectionPoint;
+import org.apache.deltaspike.core.util.metadata.builder.ImmutableInjectionPoint;
 
 import javax.enterprise.inject.Typed;
 import javax.enterprise.inject.spi.AnnotatedMethod;

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/78d0434e/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/metadata/builder/AnnotatedCallableImpl.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/metadata/builder/AnnotatedCallableImpl.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/metadata/builder/AnnotatedCallableImpl.java
new file mode 100644
index 0000000..5562f35
--- /dev/null
+++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/metadata/builder/AnnotatedCallableImpl.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.apache.deltaspike.core.util.metadata.builder;
+
+import javax.enterprise.inject.spi.AnnotatedCallable;
+import javax.enterprise.inject.spi.AnnotatedParameter;
+import javax.enterprise.inject.spi.AnnotatedType;
+import java.lang.reflect.Member;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Implementation of {@link AnnotatedCallable}
+ */
+abstract class AnnotatedCallableImpl<X, Y extends Member> extends AnnotatedMemberImpl<X, Y>
+        implements AnnotatedCallable<X>
+{
+
+    private final List<AnnotatedParameter<X>> parameters;
+
+    protected AnnotatedCallableImpl(AnnotatedType<X> declaringType, Y member, Class<?> memberType,
+                                    Class<?>[] parameterTypes, Type[] genericTypes, AnnotationStore annotations,
+                                    Map<Integer, AnnotationStore> parameterAnnotations, Type genericType,
+                                    Map<Integer, Type> parameterTypeOverrides)
+    {
+        super(declaringType, member, memberType, annotations, genericType, null);
+        this.parameters = getAnnotatedParameters(this, parameterTypes, genericTypes, parameterAnnotations,
+                parameterTypeOverrides);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public List<AnnotatedParameter<X>> getParameters()
+    {
+        return Collections.unmodifiableList(parameters);
+    }
+
+    public AnnotatedParameter<X> getParameter(int index)
+    {
+        return parameters.get(index);
+
+    }
+
+    private static <X, Y extends Member> List<AnnotatedParameter<X>> getAnnotatedParameters(
+            AnnotatedCallableImpl<X, Y> callable, Class<?>[] parameterTypes, Type[] genericTypes,
+            Map<Integer, AnnotationStore> parameterAnnotations,
+            Map<Integer, Type> parameterTypeOverrides)
+    {
+        List<AnnotatedParameter<X>> parameters = new ArrayList<AnnotatedParameter<X>>();
+        int len = parameterTypes.length;
+
+        for (int i = 0; i < len; ++i)
+        {
+            AnnotationBuilder builder = new AnnotationBuilder();
+            if (parameterAnnotations != null && parameterAnnotations.containsKey(i))
+            {
+                builder.addAll(parameterAnnotations.get(i));
+            }
+            Type over = null;
+            if (parameterTypeOverrides != null)
+            {
+                over = parameterTypeOverrides.get(i);
+            }
+            AnnotatedParameterImpl<X> p = new AnnotatedParameterImpl<X>(
+                    callable, parameterTypes[i], i, builder.create(), genericTypes[i], over);
+
+            parameters.add(p);
+        }
+        return parameters;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/78d0434e/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/metadata/builder/AnnotatedConstructorImpl.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/metadata/builder/AnnotatedConstructorImpl.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/metadata/builder/AnnotatedConstructorImpl.java
new file mode 100644
index 0000000..2683afd
--- /dev/null
+++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/metadata/builder/AnnotatedConstructorImpl.java
@@ -0,0 +1,66 @@
+/*
+ * 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.apache.deltaspike.core.util.metadata.builder;
+
+import javax.enterprise.inject.spi.AnnotatedConstructor;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Type;
+import java.util.Map;
+
+/**
+ * Implementation of {@link AnnotatedConstructor} to be used in
+ * {@link org.apache.deltaspike.core.util.metadata.builder.AnnotatedTypeBuilder}
+ * and other CDI life cycle events.
+ */
+class AnnotatedConstructorImpl<X> extends AnnotatedCallableImpl<X, Constructor<X>> implements AnnotatedConstructor<X>
+{
+
+    /**
+     * Constructor
+     */
+    public AnnotatedConstructorImpl(AnnotatedTypeImpl<X> type, Constructor<?> constructor, AnnotationStore annotations,
+                                    Map<Integer, AnnotationStore> parameterAnnotations,
+                                    Map<Integer, Type> typeOverrides)
+    {
+
+        super(type, (Constructor<X>) constructor, constructor.getDeclaringClass(), constructor.getParameterTypes(),
+                getGenericArray(constructor), annotations, parameterAnnotations, null, typeOverrides);
+    }
+
+    private static Type[] getGenericArray(Constructor<?> constructor)
+    {
+        Type[] genericTypes = constructor.getGenericParameterTypes();
+        // for inner classes genericTypes and parameterTypes can be different
+        // length, this is a hack to fix this.
+        // TODO: investigate this behavior further, on different JVM's and
+        // compilers
+        if (genericTypes.length + 1 == constructor.getParameterTypes().length)
+        {
+            genericTypes = new Type[constructor.getGenericParameterTypes().length + 1];
+            genericTypes[0] = constructor.getParameterTypes()[0];
+            for (int i = 0; i < constructor.getGenericParameterTypes().length; ++i)
+            {
+                genericTypes[i + 1] = constructor.getGenericParameterTypes()[i];
+            }
+        }
+        return genericTypes;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/78d0434e/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/metadata/builder/AnnotatedFieldImpl.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/metadata/builder/AnnotatedFieldImpl.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/metadata/builder/AnnotatedFieldImpl.java
new file mode 100644
index 0000000..4d892d1
--- /dev/null
+++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/metadata/builder/AnnotatedFieldImpl.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.apache.deltaspike.core.util.metadata.builder;
+
+import javax.enterprise.inject.spi.AnnotatedField;
+import javax.enterprise.inject.spi.AnnotatedType;
+import java.lang.reflect.Field;
+import java.lang.reflect.Type;
+
+/**
+ * Implementation of {@link AnnotatedField} to be used in CDI life cycle events and
+ * {@link org.apache.deltaspike.core.util.metadata.builder.AnnotatedTypeBuilder}.
+ */
+class AnnotatedFieldImpl<X> extends AnnotatedMemberImpl<X, Field> implements AnnotatedField<X>
+{
+
+    /**
+     * Constructor.
+     */
+    public AnnotatedFieldImpl(AnnotatedType<X> declaringType, Field field, AnnotationStore annotations,
+                              Type overridenType)
+    {
+        super(declaringType, field, field.getType(), annotations, field.getGenericType(), overridenType);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/78d0434e/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/metadata/builder/AnnotatedImpl.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/metadata/builder/AnnotatedImpl.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/metadata/builder/AnnotatedImpl.java
new file mode 100644
index 0000000..9f0f776
--- /dev/null
+++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/metadata/builder/AnnotatedImpl.java
@@ -0,0 +1,118 @@
+/*
+ * 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.apache.deltaspike.core.util.metadata.builder;
+
+import org.apache.deltaspike.core.util.HierarchyDiscovery;
+
+import javax.enterprise.inject.spi.Annotated;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * The base class for all New Annotated types.
+ */
+abstract class AnnotatedImpl implements Annotated
+{
+
+    private final Type type;
+    private final Set<Type> typeClosure;
+    private final AnnotationStore annotations;
+
+    protected AnnotatedImpl(Class<?> type, AnnotationStore annotations, Type genericType, Type overridenType)
+    {
+        if (overridenType == null)
+        {
+            if (genericType != null)
+            {
+                typeClosure = new HierarchyDiscovery(genericType).getTypeClosure();
+                this.type = genericType;
+            }
+            else
+            {
+                typeClosure = new HierarchyDiscovery(type).getTypeClosure();
+                this.type = type;
+            }
+        }
+        else
+        {
+            this.type = overridenType;
+            this.typeClosure = Collections.singleton(overridenType);
+        }
+
+
+        if (annotations == null)
+        {
+            this.annotations = new AnnotationStore();
+        }
+        else
+        {
+            this.annotations = annotations;
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public <T extends Annotation> T getAnnotation(Class<T> annotationType)
+    {
+        return annotations.getAnnotation(annotationType);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Set<Annotation> getAnnotations()
+    {
+        return annotations.getAnnotations();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isAnnotationPresent(Class<? extends Annotation> annotationType)
+    {
+        return annotations.isAnnotationPresent(annotationType);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Set<Type> getTypeClosure()
+    {
+        return new HashSet<Type>(typeClosure);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Type getBaseType()
+    {
+        return type;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/78d0434e/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/metadata/builder/AnnotatedMemberImpl.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/metadata/builder/AnnotatedMemberImpl.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/metadata/builder/AnnotatedMemberImpl.java
new file mode 100644
index 0000000..1e6a290
--- /dev/null
+++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/metadata/builder/AnnotatedMemberImpl.java
@@ -0,0 +1,72 @@
+/*
+ * 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.apache.deltaspike.core.util.metadata.builder;
+
+import javax.enterprise.inject.spi.AnnotatedMember;
+import javax.enterprise.inject.spi.AnnotatedType;
+import java.lang.reflect.Member;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Type;
+
+/**
+ * An implementation of {@link AnnotatedMember} to be used in CDI life cycle events and
+ * {@link org.apache.deltaspike.core.util.metadata.builder.AnnotatedTypeBuilder}.
+ */
+abstract class AnnotatedMemberImpl<X, M extends Member> extends AnnotatedImpl implements AnnotatedMember<X>
+{
+    private final AnnotatedType<X> declaringType;
+    private final M javaMember;
+
+    protected AnnotatedMemberImpl(AnnotatedType<X> declaringType, M member, Class<?> memberType,
+                                  AnnotationStore annotations, Type genericType, Type overridenType)
+    {
+        super(memberType, annotations, genericType, overridenType);
+        this.declaringType = declaringType;
+        this.javaMember = member;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public AnnotatedType<X> getDeclaringType()
+    {
+        return declaringType;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public M getJavaMember()
+    {
+        return javaMember;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isStatic()
+    {
+        return Modifier.isStatic(javaMember.getModifiers());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/78d0434e/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/metadata/builder/AnnotatedMethodImpl.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/metadata/builder/AnnotatedMethodImpl.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/metadata/builder/AnnotatedMethodImpl.java
new file mode 100644
index 0000000..63e399a
--- /dev/null
+++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/metadata/builder/AnnotatedMethodImpl.java
@@ -0,0 +1,46 @@
+/*
+ * 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.apache.deltaspike.core.util.metadata.builder;
+
+import javax.enterprise.inject.spi.AnnotatedMethod;
+import javax.enterprise.inject.spi.AnnotatedType;
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.util.Map;
+
+/**
+ * Implementation of {@link AnnotatedMethod} to be used in CDI life cycle events and
+ * {@link org.apache.deltaspike.core.util.metadata.builder.AnnotatedTypeBuilder}.
+ */
+class AnnotatedMethodImpl<X> extends AnnotatedCallableImpl<X, Method> implements AnnotatedMethod<X>
+{
+    /**
+     * Constructor.
+     */
+    public AnnotatedMethodImpl(AnnotatedType<X> type,
+                               Method method,
+                               AnnotationStore annotations,
+                               Map<Integer, AnnotationStore> parameterAnnotations,
+                               Map<Integer, Type> parameterTypeOverrides)
+    {
+        super(type, method, method.getReturnType(), method.getParameterTypes(), method.getGenericParameterTypes(),
+                annotations, parameterAnnotations, method.getGenericReturnType(), parameterTypeOverrides);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/78d0434e/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/metadata/builder/AnnotatedParameterImpl.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/metadata/builder/AnnotatedParameterImpl.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/metadata/builder/AnnotatedParameterImpl.java
new file mode 100644
index 0000000..916e1b2
--- /dev/null
+++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/metadata/builder/AnnotatedParameterImpl.java
@@ -0,0 +1,64 @@
+/*
+ * 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.apache.deltaspike.core.util.metadata.builder;
+
+import javax.enterprise.inject.spi.AnnotatedCallable;
+import javax.enterprise.inject.spi.AnnotatedParameter;
+import java.lang.reflect.Type;
+
+/**
+ * Implementation of {@link AnnotatedParameter}.
+ */
+class AnnotatedParameterImpl<X> extends AnnotatedImpl implements AnnotatedParameter<X>
+{
+
+    private final int position;
+    private final AnnotatedCallable<X> declaringCallable;
+
+    /**
+     * Constructor
+     */
+    public AnnotatedParameterImpl(AnnotatedCallable<X> declaringCallable, Class<?> type, int position,
+                                  AnnotationStore annotations, Type genericType, Type typeOverride)
+    {
+        super(type, annotations, genericType, typeOverride);
+        this.declaringCallable = declaringCallable;
+        this.position = position;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public AnnotatedCallable<X> getDeclaringCallable()
+    {
+        return declaringCallable;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int getPosition()
+    {
+        return position;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/78d0434e/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/metadata/builder/AnnotatedTypeBuilder.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/metadata/builder/AnnotatedTypeBuilder.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/metadata/builder/AnnotatedTypeBuilder.java
new file mode 100644
index 0000000..9aa072e
--- /dev/null
+++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/metadata/builder/AnnotatedTypeBuilder.java
@@ -0,0 +1,959 @@
+/*
+ * 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.apache.deltaspike.core.util.metadata.builder;
+
+import org.apache.deltaspike.core.util.ReflectionUtils;
+
+import javax.enterprise.inject.spi.Annotated;
+import javax.enterprise.inject.spi.AnnotatedConstructor;
+import javax.enterprise.inject.spi.AnnotatedField;
+import javax.enterprise.inject.spi.AnnotatedMethod;
+import javax.enterprise.inject.spi.AnnotatedParameter;
+import javax.enterprise.inject.spi.AnnotatedType;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Builder to aid in creation of a new {@link AnnotatedType} for use in CDI life cycle events.
+ * Using the builder is typically done by reading the annotations from a {@link Class} or an
+ * {@link AnnotatedType}. Once the starting class or type has been added all of annotations
+ * can be modified: constructor, parameter, class, method and fields.
+ *
+ * The AnnotatedTypeBuilder is not thread safe and shall not be used concurrently!
+ */
+public class AnnotatedTypeBuilder<X>
+{
+    private Class<X> javaClass;
+    private final AnnotationBuilder typeAnnotations;
+
+    private final Map<Constructor<?>, AnnotationBuilder> constructors;
+    private final Map<Constructor<?>, Map<Integer, AnnotationBuilder>> constructorParameters;
+    private final Map<Constructor<?>, Map<Integer, Type>> constructorParameterTypes;
+
+    private final Map<Field, AnnotationBuilder> fields;
+    private final Map<Field, Type> fieldTypes;
+
+    private final Map<Method, AnnotationBuilder> methods;
+    private final Map<Method, Map<Integer, AnnotationBuilder>> methodParameters;
+    private final Map<Method, Map<Integer, Type>> methodParameterTypes;
+
+    /**
+     * Create a new builder. A new builder has no annotations and no members.
+     *
+     * @see #readFromType(AnnotatedType)
+     * @see #readFromType(Class)
+     * @see #readFromType(AnnotatedType, boolean)
+     * @see #readFromType(Class, boolean)
+     */
+    public AnnotatedTypeBuilder()
+    {
+        this.typeAnnotations = new AnnotationBuilder();
+        this.constructors = new HashMap<Constructor<?>, AnnotationBuilder>();
+        this.constructorParameters = new HashMap<Constructor<?>, Map<Integer, AnnotationBuilder>>();
+        this.constructorParameterTypes = new HashMap<Constructor<?>, Map<Integer, Type>>();
+        this.fields = new HashMap<Field, AnnotationBuilder>();
+        this.fieldTypes = new HashMap<Field, Type>();
+        this.methods = new HashMap<Method, AnnotationBuilder>();
+        this.methodParameters = new HashMap<Method, Map<Integer, AnnotationBuilder>>();
+        this.methodParameterTypes = new HashMap<Method, Map<Integer, Type>>();
+    }
+
+    /**
+     * Add an annotation to the type declaration.
+     *
+     * @param annotation the annotation instance to add
+     * @throws IllegalArgumentException if the annotation is null
+     */
+    public AnnotatedTypeBuilder<X> addToClass(Annotation annotation)
+    {
+        typeAnnotations.add(annotation);
+        return this;
+    }
+
+    /**
+     * Remove an annotation from the type
+     *
+     * @param annotationType the annotation type to remove
+     * @throws IllegalArgumentException if the annotationType
+     */
+    public AnnotatedTypeBuilder<X> removeFromClass(Class<? extends Annotation> annotationType)
+    {
+        typeAnnotations.remove(annotationType);
+        return this;
+    }
+
+    /**
+     * Add an annotation to the specified field. If the field is not already
+     * present, it will be added.
+     *
+     * @param field      the field to add the annotation to
+     * @param annotation the annotation to add
+     * @throws IllegalArgumentException if the annotation is null
+     */
+    public AnnotatedTypeBuilder<X> addToField(Field field, Annotation annotation)
+    {
+        if (fields.get(field) == null)
+        {
+            fields.put(field, new AnnotationBuilder());
+        }
+        fields.get(field).add(annotation);
+        return this;
+    }
+
+    /**
+     * Add an annotation to the specified field. If the field is not already
+     * present, it will be added.
+     *
+     * @param field      the field to add the annotation to
+     * @param annotation the annotation to add
+     * @throws IllegalArgumentException if the annotation is null
+     */
+    public AnnotatedTypeBuilder<X> addToField(AnnotatedField<? super X> field, Annotation annotation)
+    {
+        return addToField(field.getJavaMember(), annotation);
+    }
+
+    /**
+     * Remove an annotation from the specified field.
+     *
+     * @param field          the field to remove the annotation from
+     * @param annotationType the annotation type to remove
+     * @throws IllegalArgumentException if the annotationType is null or if the
+     *                                  field is not currently declared on the type
+     */
+    public AnnotatedTypeBuilder<X> removeFromField(Field field, Class<? extends Annotation> annotationType)
+    {
+        if (fields.get(field) == null)
+        {
+            throw new IllegalArgumentException("field " + field + " not present on class " + getJavaClass());
+        }
+        else
+        {
+            fields.get(field).remove(annotationType);
+        }
+        return this;
+    }
+
+    /**
+     * Remove an annotation from the specified field.
+     *
+     * @param field          the field to remove the annotation from
+     * @param annotationType the annotation type to remove
+     * @throws IllegalArgumentException if the annotationType is null or if the
+     *                                  field is not currently declared on the type
+     */
+    public AnnotatedTypeBuilder<X> removeFromField(AnnotatedField<? super X> field,
+                                                   Class<? extends Annotation> annotationType)
+    {
+        return removeFromField(field.getJavaMember(), annotationType);
+    }
+
+    /**
+     * Add an annotation to the specified method. If the method is not already
+     * present, it will be added.
+     *
+     * @param method     the method to add the annotation to
+     * @param annotation the annotation to add
+     * @throws IllegalArgumentException if the annotation is null
+     */
+    public AnnotatedTypeBuilder<X> addToMethod(Method method, Annotation annotation)
+    {
+        if (methods.get(method) == null)
+        {
+            methods.put(method, new AnnotationBuilder());
+        }
+        methods.get(method).add(annotation);
+        return this;
+    }
+
+    /**
+     * Add an annotation to the specified method. If the method is not already
+     * present, it will be added.
+     *
+     * @param method     the method to add the annotation to
+     * @param annotation the annotation to add
+     * @throws IllegalArgumentException if the annotation is null
+     */
+    public AnnotatedTypeBuilder<X> addToMethod(AnnotatedMethod<? super X> method, Annotation annotation)
+    {
+        return addToMethod(method.getJavaMember(), annotation);
+    }
+
+    /**
+     * Remove an annotation from the specified method.
+     *
+     * @param method         the method to remove the annotation from
+     * @param annotationType the annotation type to remove
+     * @throws IllegalArgumentException if the annotationType is null or if the
+     *                                  method is not currently declared on the type
+     */
+    public AnnotatedTypeBuilder<X> removeFromMethod(Method method, Class<? extends Annotation> annotationType)
+    {
+        if (methods.get(method) == null)
+        {
+            throw new IllegalArgumentException("Method " + method + " not present on class" + getJavaClass());
+        }
+        else
+        {
+            methods.get(method).remove(annotationType);
+        }
+        return this;
+    }
+
+    /**
+     * Remove an annotation from the specified method.
+     *
+     * @param method         the method to remove the annotation from
+     * @param annotationType the annotation type to remove
+     * @throws IllegalArgumentException if the annotationType is null or if the
+     *                                  method is not currently declared on the type
+     */
+    public AnnotatedTypeBuilder<X> removeFromMethod(AnnotatedMethod<? super X> method,
+                                                    Class<? extends Annotation> annotationType)
+    {
+        return removeFromMethod(method.getJavaMember(), annotationType);
+    }
+
+    /**
+     * Add an annotation to the specified method parameter. If the method is not
+     * already present, it will be added. If the method parameter is not already
+     * present, it will be added.
+     *
+     * @param method     the method to add the annotation to
+     * @param position   the position of the parameter to add
+     * @param annotation the annotation to add
+     * @throws IllegalArgumentException if the annotation is null
+     */
+    public AnnotatedTypeBuilder<X> addToMethodParameter(Method method, int position, Annotation annotation)
+    {
+        if (!methods.containsKey(method))
+        {
+            methods.put(method, new AnnotationBuilder());
+        }
+        if (methodParameters.get(method) == null)
+        {
+            methodParameters.put(method, new HashMap<Integer, AnnotationBuilder>());
+        }
+        if (methodParameters.get(method).get(position) == null)
+        {
+            methodParameters.get(method).put(position, new AnnotationBuilder());
+        }
+        methodParameters.get(method).get(position).add(annotation);
+        return this;
+    }
+
+    /**
+     * Remove an annotation from the specified method parameter.
+     *
+     * @param method         the method to remove the annotation from
+     * @param position       the position of the parameter to remove
+     * @param annotationType the annotation type to remove
+     * @throws IllegalArgumentException if the annotationType is null, if the
+     *                                  method is not currently declared on the type or if the
+     *                                  parameter is not declared on the method
+     */
+    public AnnotatedTypeBuilder<X> removeFromMethodParameter(Method method,
+                                                             int position, Class<? extends Annotation> annotationType)
+    {
+        if (methods.get(method) == null)
+        {
+            throw new IllegalArgumentException("Method " + method + " not present on class " + getJavaClass());
+        }
+        else
+        {
+            if (methodParameters.get(method).get(position) == null)
+            {
+                throw new IllegalArgumentException(
+                        String.format("parameter %s not present on method %s declared on class %s",
+                        method, position, getJavaClass()));
+            }
+            else
+            {
+                methodParameters.get(method).get(position).remove(annotationType);
+            }
+        }
+        return this;
+    }
+
+    /**
+     * Add an annotation to the specified constructor. If the constructor is not
+     * already present, it will be added.
+     *
+     * @param constructor the constructor to add the annotation to
+     * @param annotation  the annotation to add
+     * @throws IllegalArgumentException if the annotation is null
+     */
+    public AnnotatedTypeBuilder<X> addToConstructor(Constructor<X> constructor, Annotation annotation)
+    {
+        if (constructors.get(constructor) == null)
+        {
+            constructors.put(constructor, new AnnotationBuilder());
+        }
+        constructors.get(constructor).add(annotation);
+        return this;
+    }
+
+    /**
+     * Add an annotation to the specified constructor. If the constructor is not
+     * already present, it will be added.
+     *
+     * @param constructor the constructor to add the annotation to
+     * @param annotation  the annotation to add
+     * @throws IllegalArgumentException if the annotation is null
+     */
+    public AnnotatedTypeBuilder<X> addToConstructor(AnnotatedConstructor<X> constructor, Annotation annotation)
+    {
+        return addToConstructor(constructor.getJavaMember(), annotation);
+    }
+
+    /**
+     * Remove an annotation from the specified constructor.
+     *
+     * @param constructor    the constructor to add the annotation to
+     * @param annotationType the annotation to add
+     * @throws IllegalArgumentException if the annotationType is null or if the
+     *                                  constructor is not currently declared on the type
+     */
+    public AnnotatedTypeBuilder<X> removeFromConstructor(Constructor<X> constructor,
+                                                         Class<? extends Annotation> annotationType)
+    {
+        if (constructors.get(constructor) != null)
+        {
+            constructors.get(constructor).remove(annotationType);
+        }
+        return this;
+    }
+
+    /**
+     * Remove an annotation from the specified constructor.
+     *
+     * @param constructor    the constructor to add the annotation to
+     * @param annotationType the annotation to add
+     * @throws IllegalArgumentException if the annotationType is null, if the
+     *                                  annotation does not exist on the type or if the constructor is
+     *                                  not currently declared on the type
+     */
+    public AnnotatedTypeBuilder<X> removeFromConstructor(AnnotatedConstructor<X> constructor,
+                                                         Class<? extends Annotation> annotationType)
+    {
+        return removeFromConstructor(constructor.getJavaMember(), annotationType);
+    }
+
+    /**
+     * Add an annotation to the specified constructor parameter. If the
+     * constructor is not already present, it will be added. If the constructor
+     * parameter is not already present, it will be added.
+     *
+     * @param constructor the constructor to add the annotation to
+     * @param position    the position of the parameter to add
+     * @param annotation  the annotation to add
+     * @throws IllegalArgumentException if the annotation is null
+     */
+    public AnnotatedTypeBuilder<X> addToConstructorParameter(Constructor<X> constructor,
+                                                             int position,
+                                                             Annotation annotation)
+    {
+        if (!constructors.containsKey(constructor))
+        {
+            constructors.put(constructor, new AnnotationBuilder());
+        }
+        if (constructorParameters.get(constructor) == null)
+        {
+            constructorParameters.put(constructor, new HashMap<Integer, AnnotationBuilder>());
+        }
+        if (constructorParameters.get(constructor).get(position) == null)
+        {
+            constructorParameters.get(constructor).put(position, new AnnotationBuilder());
+        }
+        constructorParameters.get(constructor).get(position).add(annotation);
+        return this;
+    }
+
+    /**
+     * Remove an annotation from the specified constructor parameter.
+     *
+     * @param constructor    the constructor to remove the annotation from
+     * @param position       the position of the parameter to remove
+     * @param annotationType the annotation type to remove
+     * @throws IllegalArgumentException if the annotationType is null, if the
+     *                                  constructor is not currently declared on the type or if the
+     *                                  parameter is not declared on the constructor
+     */
+    public AnnotatedTypeBuilder<X> removeFromConstructorParameter(Constructor<X> constructor,
+                                                                  int position,
+                                                                  Class<? extends Annotation> annotationType)
+    {
+        if (constructorParameters.get(constructor) != null &&
+            constructorParameters.get(constructor).get(position) != null)
+        {
+            constructorParameters.get(constructor).get(position).remove(annotationType);
+        }
+        return this;
+    }
+
+    /**
+     * Remove an annotation from the specified parameter.
+     *
+     * @param parameter      the parameter to remove the annotation from
+     * @param annotationType the annotation type to remove
+     * @throws IllegalArgumentException if the annotationType is null, if the
+     *                                  callable which declares the parameter is not currently declared
+     *                                  on the type or if the parameter is not declared on either a
+     *                                  constructor or a method
+     */
+    public AnnotatedTypeBuilder<X> removeFromParameter(AnnotatedParameter<? super X> parameter,
+                                                       Class<? extends Annotation> annotationType)
+    {
+        if (parameter.getDeclaringCallable().getJavaMember() instanceof Method)
+        {
+            Method method = (Method) parameter.getDeclaringCallable().getJavaMember();
+            return removeFromMethodParameter(method, parameter.getPosition(), annotationType);
+        }
+        if (parameter.getDeclaringCallable().getJavaMember() instanceof Constructor<?>)
+        {
+            @SuppressWarnings("unchecked")
+            Constructor<X> constructor = (Constructor<X>) parameter.getDeclaringCallable().getJavaMember();
+            return removeFromConstructorParameter(constructor, parameter.getPosition(), annotationType);
+        }
+        else
+        {
+            throw new IllegalArgumentException("Cannot remove from parameter " + parameter +
+                    " - cannot operate on member " + parameter.getDeclaringCallable().getJavaMember());
+        }
+    }
+
+    /**
+     * Add an annotation to the specified parameter. If the callable which
+     * declares the parameter is not already present, it will be added. If the
+     * parameter is not already present on the callable, it will be added.
+     *
+     * @param parameter  the parameter to add the annotation to
+     * @param annotation the annotation to add
+     * @throws IllegalArgumentException if the annotation is null or if the
+     *                                  parameter is not declared on either a constructor or a method
+     */
+    public AnnotatedTypeBuilder<X> addToParameter(AnnotatedParameter<? super X> parameter, Annotation annotation)
+    {
+        if (parameter.getDeclaringCallable().getJavaMember() instanceof Method)
+        {
+            Method method = (Method) parameter.getDeclaringCallable().getJavaMember();
+            return addToMethodParameter(method, parameter.getPosition(), annotation);
+        }
+        if (parameter.getDeclaringCallable().getJavaMember() instanceof Constructor<?>)
+        {
+            @SuppressWarnings("unchecked")
+            Constructor<X> constructor = (Constructor<X>) parameter.getDeclaringCallable().getJavaMember();
+            return addToConstructorParameter(constructor, parameter.getPosition(), annotation);
+        }
+        else
+        {
+            throw new IllegalArgumentException("Cannot remove from parameter " + parameter +
+                    " - cannot operate on member " + parameter.getDeclaringCallable().getJavaMember());
+        }
+    }
+
+    /**
+     * Remove annotations from the type, and all of it's members. If an
+     * annotation of the specified type appears on the type declaration, or any
+     * of it's members it will be removed.
+     *
+     * @param annotationType the type of annotation to remove
+     * @throws IllegalArgumentException if the annotationType is null
+     */
+    public AnnotatedTypeBuilder<X> removeFromAll(Class<? extends Annotation> annotationType)
+    {
+        if (annotationType == null)
+        {
+            throw new IllegalArgumentException(String.format("%s parameter must not be null", "annotationType"));
+        }
+        removeFromClass(annotationType);
+        for (Map.Entry<Field, AnnotationBuilder> field : fields.entrySet())
+        {
+            field.getValue().remove(annotationType);
+        }
+        for (Map.Entry<Method, AnnotationBuilder> method : methods.entrySet())
+        {
+            method.getValue().remove(annotationType);
+            if (methodParameters.get(method.getKey()) != null)
+            {
+                for (Map.Entry<Integer, AnnotationBuilder> parameter : methodParameters.get(method.getKey()).entrySet())
+                {
+                    parameter.getValue().remove(annotationType);
+                }
+            }
+        }
+        for (Map.Entry<Constructor<?>, AnnotationBuilder> constructor : constructors.entrySet())
+        {
+            constructor.getValue().remove(annotationType);
+            if (constructorParameters.get(constructor.getKey()) != null)
+            {
+                for (Map.Entry<Integer, AnnotationBuilder> parameter :
+                        constructorParameters.get(constructor.getKey()).entrySet())
+                {
+                    parameter.getValue().remove(annotationType);
+                }
+            }
+        }
+        return this;
+    }
+
+    /**
+     * Reads in from an existing AnnotatedType. Any elements not present are
+     * added. The javaClass will be read in. If the annotation already exists on
+     * that element in the builder the read annotation will be used.
+     *
+     * @param type the type to read from
+     * @throws IllegalArgumentException if type is null
+     */
+    public AnnotatedTypeBuilder<X> readFromType(AnnotatedType<X> type)
+    {
+        return readFromType(type, true);
+    }
+
+    /**
+     * Reads in from an existing AnnotatedType. Any elements not present are
+     * added. The javaClass will be read in if overwrite is true. If the
+     * annotation already exists on that element in the builder, overwrite
+     * determines whether the original or read annotation will be used.
+     *
+     * @param type      the type to read from
+     * @param overwrite if true, the read annotation will replace any existing
+     *                  annotation
+     * @throws IllegalArgumentException if type is null
+     */
+    public AnnotatedTypeBuilder<X> readFromType(AnnotatedType<X> type, boolean overwrite)
+    {
+        if (type == null)
+        {
+            throw new IllegalArgumentException(String.format("%s parameter must not be null", "type"));
+        }
+        if (javaClass == null || overwrite)
+        {
+            this.javaClass = type.getJavaClass();
+        }
+        mergeAnnotationsOnElement(type, overwrite, typeAnnotations);
+        for (AnnotatedField<? super X> field : type.getFields())
+        {
+            if (fields.get(field.getJavaMember()) == null)
+            {
+                fields.put(field.getJavaMember(), new AnnotationBuilder());
+            }
+            mergeAnnotationsOnElement(field, overwrite, fields.get(field.getJavaMember()));
+        }
+        for (AnnotatedMethod<? super X> method : type.getMethods())
+        {
+            if (methods.get(method.getJavaMember()) == null)
+            {
+                methods.put(method.getJavaMember(), new AnnotationBuilder());
+            }
+            mergeAnnotationsOnElement(method, overwrite, methods.get(method.getJavaMember()));
+            for (AnnotatedParameter<? super X> p : method.getParameters())
+            {
+                if (methodParameters.get(method.getJavaMember()) == null)
+                {
+                    methodParameters.put(method.getJavaMember(), new HashMap<Integer, AnnotationBuilder>());
+                }
+                if (methodParameters.get(method.getJavaMember()).get(p.getPosition()) == null)
+                {
+                    methodParameters.get(method.getJavaMember()).put(p.getPosition(), new AnnotationBuilder());
+                }
+                mergeAnnotationsOnElement(
+                        p, overwrite, methodParameters.get(method.getJavaMember()).get(p.getPosition()));
+            }
+        }
+        for (AnnotatedConstructor<? super X> constructor : type.getConstructors())
+        {
+            if (constructors.get(constructor.getJavaMember()) == null)
+            {
+                constructors.put(constructor.getJavaMember(), new AnnotationBuilder());
+            }
+            mergeAnnotationsOnElement(constructor, overwrite, constructors.get(constructor.getJavaMember()));
+            for (AnnotatedParameter<? super X> p : constructor.getParameters())
+            {
+                if (constructorParameters.get(
+                        constructor.getJavaMember()) == null)
+                {
+                    constructorParameters.put(
+                        constructor.getJavaMember(), new HashMap<Integer, AnnotationBuilder>());
+                }
+                if (constructorParameters.get(
+                        constructor.getJavaMember()).get(p.getPosition()) == null)
+                {
+                    constructorParameters.get(
+                        constructor.getJavaMember()).put(p.getPosition(), new AnnotationBuilder());
+                }
+                mergeAnnotationsOnElement(
+                        p, overwrite, constructorParameters.get(constructor.getJavaMember()).get(p.getPosition()));
+            }
+        }
+        return this;
+    }
+
+    /**
+     * Reads the annotations from an existing java type. Annotations already
+     * present will be overwritten
+     *
+     * @param type the type to read from
+     * @throws IllegalArgumentException if type is null
+     */
+    public AnnotatedTypeBuilder<X> readFromType(Class<X> type)
+    {
+        return readFromType(type, true);
+    }
+
+    /**
+     * Reads the annotations from an existing java type. If overwrite is true
+     * then existing annotations will be overwritten
+     *
+     * @param type      the type to read from
+     * @param overwrite if true, the read annotation will replace any existing
+     *                  annotation
+     */
+    public AnnotatedTypeBuilder<X> readFromType(Class<X> type, boolean overwrite)
+    {
+        if (type == null)
+        {
+            throw new IllegalArgumentException(String.format("%s parameter must not be null", "type"));
+        }
+        if (javaClass == null || overwrite)
+        {
+            this.javaClass = type;
+        }
+        for (Annotation annotation : type.getAnnotations())
+        {
+            if (overwrite || !typeAnnotations.isAnnotationPresent(annotation.annotationType()))
+            {
+                typeAnnotations.add(annotation);
+            }
+        }
+
+        for (Field field : ReflectionUtils.getAllDeclaredFields(type))
+        {
+            AnnotationBuilder annotationBuilder = fields.get(field);
+            if (annotationBuilder == null)
+            {
+                annotationBuilder = new AnnotationBuilder();
+                fields.put(field, annotationBuilder);
+            }
+            ReflectionUtils.setAccessible(field);
+
+            for (Annotation annotation : field.getAnnotations())
+            {
+                if (overwrite || !annotationBuilder.isAnnotationPresent(annotation.annotationType()))
+                {
+                    annotationBuilder.add(annotation);
+                }
+            }
+        }
+
+        for (Method method : ReflectionUtils.getAllDeclaredMethods(type))
+        {
+            AnnotationBuilder annotationBuilder = methods.get(method);
+            if (annotationBuilder == null)
+            {
+                annotationBuilder = new AnnotationBuilder();
+                methods.put(method, annotationBuilder);
+            }
+            ReflectionUtils.setAccessible(method);
+
+            for (Annotation annotation : method.getAnnotations())
+            {
+                if (overwrite || !annotationBuilder.isAnnotationPresent(annotation.annotationType()))
+                {
+                    annotationBuilder.add(annotation);
+                }
+            }
+
+            Map<Integer, AnnotationBuilder> parameters = methodParameters.get(method);
+            if (parameters == null)
+            {
+                parameters = new HashMap<Integer, AnnotationBuilder>();
+                methodParameters.put(method, parameters);
+            }
+            for (int i = 0; i < method.getParameterTypes().length; ++i)
+            {
+                AnnotationBuilder parameterAnnotationBuilder = parameters.get(i);
+                if (parameterAnnotationBuilder == null)
+                {
+                    parameterAnnotationBuilder = new AnnotationBuilder();
+                    parameters.put(i, parameterAnnotationBuilder);
+                }
+                for (Annotation annotation : method.getParameterAnnotations()[i])
+                {
+                    if (overwrite || !parameterAnnotationBuilder.isAnnotationPresent(annotation.annotationType()))
+                    {
+                        parameterAnnotationBuilder.add(annotation);
+                    }
+                }
+            }
+        }
+
+        for (Constructor<?> constructor : type.getDeclaredConstructors())
+        {
+            AnnotationBuilder annotationBuilder = constructors.get(constructor);
+            if (annotationBuilder == null)
+            {
+                annotationBuilder = new AnnotationBuilder();
+                constructors.put(constructor, annotationBuilder);
+            }
+            constructor.setAccessible(true);
+            for (Annotation annotation : constructor.getAnnotations())
+            {
+                if (overwrite || !annotationBuilder.isAnnotationPresent(annotation.annotationType()))
+                {
+                    annotationBuilder.add(annotation);
+                }
+            }
+            Map<Integer, AnnotationBuilder> mparams = constructorParameters.get(constructor);
+            if (mparams == null)
+            {
+                mparams = new HashMap<Integer, AnnotationBuilder>();
+                constructorParameters.put(constructor, mparams);
+            }
+            for (int i = 0; i < constructor.getParameterTypes().length; ++i)
+            {
+                AnnotationBuilder parameterAnnotationBuilder = mparams.get(i);
+                if (parameterAnnotationBuilder == null)
+                {
+                    parameterAnnotationBuilder = new AnnotationBuilder();
+                    mparams.put(i, parameterAnnotationBuilder);
+                }
+                for (Annotation annotation : constructor.getParameterAnnotations()[i])
+                {
+                    if (overwrite || !parameterAnnotationBuilder.isAnnotationPresent(annotation.annotationType()))
+                    {
+                        annotationBuilder.add(annotation);
+                    }
+                }
+            }
+        }
+        return this;
+    }
+
+    protected void mergeAnnotationsOnElement(Annotated annotated,
+                                             boolean overwriteExisting,
+                                             AnnotationBuilder typeAnnotations)
+    {
+        for (Annotation annotation : annotated.getAnnotations())
+        {
+            if (typeAnnotations.getAnnotation(annotation.annotationType()) != null)
+            {
+                if (overwriteExisting)
+                {
+                    typeAnnotations.remove(annotation.annotationType());
+                    typeAnnotations.add(annotation);
+                }
+            }
+            else
+            {
+                typeAnnotations.add(annotation);
+            }
+        }
+    }
+
+    /**
+     * Create an {@link AnnotatedType}. Any public members present on the
+     * underlying class and not overridden by the builder will be automatically
+     * added.
+     */
+    public AnnotatedType<X> create()
+    {
+        Map<Constructor<?>, Map<Integer, AnnotationStore>> constructorParameterAnnnotations =
+                new HashMap<Constructor<?>, Map<Integer, AnnotationStore>>();
+        Map<Constructor<?>, AnnotationStore> constructorAnnotations =
+                new HashMap<Constructor<?>, AnnotationStore>();
+        Map<Method, Map<Integer, AnnotationStore>> methodParameterAnnnotations =
+                new HashMap<Method, Map<Integer, AnnotationStore>>();
+        Map<Method, AnnotationStore> methodAnnotations =
+                new HashMap<Method, AnnotationStore>();
+        Map<Field, AnnotationStore> fieldAnnotations =
+                new HashMap<Field, AnnotationStore>();
+
+        for (Map.Entry<Field, AnnotationBuilder> field : fields.entrySet())
+        {
+            fieldAnnotations.put(field.getKey(), field.getValue().create());
+        }
+
+        for (Map.Entry<Method, AnnotationBuilder> method : methods.entrySet())
+        {
+            methodAnnotations.put(method.getKey(), method.getValue().create());
+        }
+        for (Map.Entry<Method, Map<Integer, AnnotationBuilder>> parameters : methodParameters.entrySet())
+        {
+            Map<Integer, AnnotationStore> parameterAnnotations = new HashMap<Integer, AnnotationStore>();
+            methodParameterAnnnotations.put(parameters.getKey(), parameterAnnotations);
+            for (Map.Entry<Integer, AnnotationBuilder> parameter : parameters.getValue().entrySet())
+            {
+                parameterAnnotations.put(parameter.getKey(), parameter.getValue().create());
+            }
+        }
+
+        for (Map.Entry<Constructor<?>, AnnotationBuilder> constructor : constructors.entrySet())
+        {
+            constructorAnnotations.put(constructor.getKey(), constructor.getValue().create());
+        }
+        for (Map.Entry<Constructor<?>, Map<Integer, AnnotationBuilder>> parameters : constructorParameters.entrySet())
+        {
+            Map<Integer, AnnotationStore> parameterAnnotations = new HashMap<Integer, AnnotationStore>();
+            constructorParameterAnnnotations.put(parameters.getKey(), parameterAnnotations);
+            for (Map.Entry<Integer, AnnotationBuilder> parameter : parameters.getValue().entrySet())
+            {
+                parameterAnnotations.put(parameter.getKey(), parameter.getValue().create());
+            }
+        }
+
+        return new AnnotatedTypeImpl<X>(javaClass, typeAnnotations.create(), fieldAnnotations, methodAnnotations,
+                methodParameterAnnnotations, constructorAnnotations, constructorParameterAnnnotations, fieldTypes,
+                methodParameterTypes, constructorParameterTypes);
+    }
+
+    /**
+     * Override the declared type of a field
+     *
+     * @param field the field to override the type on
+     * @param type  the new type of the field
+     * @throws IllegalArgumentException if field or type is null
+     */
+    public void overrideFieldType(Field field, Type type)
+    {
+        if (field == null)
+        {
+            throw new IllegalArgumentException(String.format("%s parameter must not be null", "field"));
+        }
+        if (type == null)
+        {
+            throw new IllegalArgumentException(String.format("%s parameter must not be null", "type"));
+        }
+        fieldTypes.put(field, type);
+    }
+
+    /**
+     * Override the declared type of a field
+     *
+     * @param field the field to override the type on
+     * @param type  the new type of the field
+     * @throws IllegalArgumentException if field or type is null
+     */
+    public void overrideFieldType(AnnotatedField<? super X> field, Type type)
+    {
+        overrideFieldType(field.getJavaMember(), type);
+    }
+
+    /**
+     * Override the declared type of a method parameter
+     *
+     * @param method   the method to override the parameter type on
+     * @param position the position of the parameter to override the type on
+     * @param type     the new type of the parameter
+     * @throws IllegalArgumentException if parameter or type is null
+     */
+    public AnnotatedTypeBuilder<X> overrideMethodParameterType(Method method, int position, Type type)
+    {
+        if (method == null)
+        {
+            throw new IllegalArgumentException(String.format("%s parameter must not be null", "method"));
+        }
+        if (type == null)
+        {
+            throw new IllegalArgumentException(String.format("%s parameter must not be null", "type"));
+        }
+        if (methodParameterTypes.get(method) == null)
+        {
+            methodParameterTypes.put(method, new HashMap<Integer, Type>());
+        }
+        methodParameterTypes.get(method).put(position, type);
+        return this;
+    }
+
+    /**
+     * Override the declared type of a constructor parameter
+     *
+     * @param constructor the constructor to override the parameter type on
+     * @param position    the position of the parameter to override the type on
+     * @param type        the new type of the parameter
+     * @throws IllegalArgumentException if parameter or type is null
+     */
+    public AnnotatedTypeBuilder<X> overrideConstructorParameterType(Constructor<X> constructor, int position, Type type)
+    {
+        if (constructor == null)
+        {
+            throw new IllegalArgumentException(String.format("%s parameter must not be null", "constructor"));
+        }
+        if (type == null)
+        {
+            throw new IllegalArgumentException(String.format("%s parameter must not be null", "type"));
+        }
+        if (constructorParameterTypes.get(constructor) == null)
+        {
+            constructorParameterTypes.put(constructor, new HashMap<Integer, Type>());
+        }
+        constructorParameterTypes.get(constructor).put(position, type);
+        return this;
+    }
+
+    /**
+     * Override the declared type of a parameter.
+     *
+     * @param parameter the parameter to override the type on
+     * @param type      the new type of the parameter
+     * @throws IllegalArgumentException if parameter or type is null
+     */
+    public AnnotatedTypeBuilder<X> overrideParameterType(AnnotatedParameter<? super X> parameter, Type type)
+    {
+        if (parameter.getDeclaringCallable().getJavaMember() instanceof Method)
+        {
+            Method method = (Method) parameter.getDeclaringCallable().getJavaMember();
+            return overrideMethodParameterType(method, parameter.getPosition(), type);
+        }
+        if (parameter.getDeclaringCallable().getJavaMember() instanceof Constructor<?>)
+        {
+            @SuppressWarnings("unchecked")
+            Constructor<X> constructor = (Constructor<X>) parameter.getDeclaringCallable().getJavaMember();
+            return overrideConstructorParameterType(constructor, parameter.getPosition(), type);
+        }
+        else
+        {
+            throw new IllegalArgumentException("Cannot remove from parameter " + parameter +
+                    " - cannot operate on member " + parameter.getDeclaringCallable().getJavaMember());
+        }
+    }
+
+    /**
+     * getter for the class
+     */
+    public Class<X> getJavaClass()
+    {
+        return javaClass;
+    }
+
+    /**
+     * setter for the class
+     */
+    public AnnotatedTypeBuilder<X> setJavaClass(Class<X> javaClass)
+    {
+        this.javaClass = javaClass;
+        return this;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/78d0434e/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/metadata/builder/AnnotatedTypeImpl.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/metadata/builder/AnnotatedTypeImpl.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/metadata/builder/AnnotatedTypeImpl.java
new file mode 100644
index 0000000..b79b93c
--- /dev/null
+++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/metadata/builder/AnnotatedTypeImpl.java
@@ -0,0 +1,163 @@
+/*
+ * 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.apache.deltaspike.core.util.metadata.builder;
+
+import javax.enterprise.inject.spi.AnnotatedConstructor;
+import javax.enterprise.inject.spi.AnnotatedField;
+import javax.enterprise.inject.spi.AnnotatedMethod;
+import javax.enterprise.inject.spi.AnnotatedType;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * An implementation of {@link AnnotatedType} to be used in CDI life cycle events and
+ * {@link org.apache.deltaspike.core.util.metadata.builder.AnnotatedTypeBuilder}.
+ */
+class AnnotatedTypeImpl<X> extends AnnotatedImpl implements AnnotatedType<X>
+{
+
+    private final Set<AnnotatedConstructor<X>> constructors;
+    private final Set<AnnotatedField<? super X>> fields;
+    private final Set<AnnotatedMethod<? super X>> methods;
+
+    private final Class<X> javaClass;
+
+    /**
+     * We make sure that there is a NewAnnotatedMember for every public
+     * method/field/constructor
+     * <p/>
+     * If annotation have been added to other methods as well we add them to
+     */
+    AnnotatedTypeImpl(Class<X> clazz,
+                      AnnotationStore typeAnnotations,
+                      Map<Field, AnnotationStore> fieldAnnotations,
+                      Map<Method, AnnotationStore> methodAnnotations,
+                      Map<Method, Map<Integer, AnnotationStore>> methodParameterAnnotations,
+                      Map<Constructor<?>, AnnotationStore> constructorAnnotations,
+                      Map<Constructor<?>, Map<Integer, AnnotationStore>> constructorParameterAnnotations,
+                      Map<Field, Type> fieldTypes,
+                      Map<Method, Map<Integer, Type>> methodParameterTypes,
+                      Map<Constructor<?>, Map<Integer, Type>> constructorParameterTypes)
+    {
+        super(clazz, typeAnnotations, null, null);
+        this.javaClass = clazz;
+        this.constructors = new HashSet<AnnotatedConstructor<X>>();
+        Set<Constructor<?>> cset = new HashSet<Constructor<?>>();
+        Set<Method> mset = new HashSet<Method>();
+        Set<Field> fset = new HashSet<Field>();
+        for (Constructor<?> c : clazz.getConstructors())
+        {
+            AnnotatedConstructor<X> nc = new AnnotatedConstructorImpl<X>(
+                    this, c, constructorAnnotations.get(c), constructorParameterAnnotations.get(c),
+                    constructorParameterTypes.get(c));
+            constructors.add(nc);
+            cset.add(c);
+        }
+        for (Map.Entry<Constructor<?>, AnnotationStore> c : constructorAnnotations.entrySet())
+        {
+            if (!cset.contains(c.getKey()))
+            {
+                AnnotatedConstructor<X> nc = new AnnotatedConstructorImpl<X>(
+                        this, c.getKey(), c.getValue(), constructorParameterAnnotations.get(c.getKey()),
+                        constructorParameterTypes.get(c.getKey()));
+                constructors.add(nc);
+            }
+        }
+        this.methods = new HashSet<AnnotatedMethod<? super X>>();
+        for (Method m : clazz.getMethods())
+        {
+            if (!m.getDeclaringClass().equals(Object.class))
+            {
+                AnnotatedMethodImpl<X> met = new AnnotatedMethodImpl<X>(this, m, methodAnnotations.get(m),
+                        methodParameterAnnotations.get(m), methodParameterTypes.get(m));
+                methods.add(met);
+                mset.add(m);
+            }
+        }
+        for (Map.Entry<Method, AnnotationStore> c : methodAnnotations.entrySet())
+        {
+            if (!c.getKey().getDeclaringClass().equals(Object.class) && !mset.contains(c.getKey()))
+            {
+                AnnotatedMethodImpl<X> nc = new AnnotatedMethodImpl<X>(
+                        this, c.getKey(),
+                        c.getValue(),
+                        methodParameterAnnotations.get(c.getKey()),
+                        methodParameterTypes.get(c.getKey()));
+                methods.add(nc);
+            }
+        }
+        this.fields = new HashSet<AnnotatedField<? super X>>();
+        for (Field f : clazz.getFields())
+        {
+            AnnotatedField<X> b = new AnnotatedFieldImpl<X>(this, f, fieldAnnotations.get(f), fieldTypes.get(f));
+            fields.add(b);
+            fset.add(f);
+        }
+        for (Map.Entry<Field, AnnotationStore> e : fieldAnnotations.entrySet())
+        {
+            if (!fset.contains(e.getKey()))
+            {
+                fields.add(new AnnotatedFieldImpl<X>(this, e.getKey(), e.getValue(), fieldTypes.get(e.getKey())));
+            }
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Set<AnnotatedConstructor<X>> getConstructors()
+    {
+        return Collections.unmodifiableSet(constructors);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Set<AnnotatedField<? super X>> getFields()
+    {
+        return Collections.unmodifiableSet(fields);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Class<X> getJavaClass()
+    {
+        return javaClass;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Set<AnnotatedMethod<? super X>> getMethods()
+    {
+        return Collections.unmodifiableSet(methods);
+    }
+}