/*
 * 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.util;

import java.io.Serializable;
import java.lang.reflect.Type;
import java.lang.reflect.AnnotatedElement;
import java.lang.annotation.Annotation;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;

/**
 * Used to declare and access metainfo about types.
 */
public final class MetaInfo
{
    private final Map<Class<?>, Object> metaInfoMap = new LinkedHashMap<Class<?>, Object>();

    public MetaInfo()
    {
    }

    public MetaInfo( MetaInfo metaInfo )
    {
        metaInfoMap.putAll( metaInfo.metaInfoMap );
    }

    public void set( Object metaInfo )
    {
        if (metaInfo instanceof Annotation)
        {
            metaInfoMap.put( metaInfo.getClass(), metaInfo );

        } else
        {
            Set<Class> types = ClassUtil.classesOf( metaInfo.getClass() );
            for( Type type : types )
            {
                if( type instanceof Class )
                {
                    metaInfoMap.put( (Class) type, metaInfo );
                }
            }
        }
    }

    public <T> T get( Class<T> metaInfoType )
    {
        return (T) metaInfoMap.get( metaInfoType );
    }

    public <T> void add( Class<T> infoType, T info )
    {
        metaInfoMap.put( infoType, info );
    }

    public MetaInfo withAnnotations( AnnotatedElement annotatedElement )
    {
        for( Annotation annotation : annotatedElement.getAnnotations() )
        {
            set( annotation );
        }
        return this;
    }
}

@@ -648,54 +648,34 @@
 ava.
-io.Serializable;%0Aimport java.lang.reflect.Type
+lang.annotation.Annotation
 ;%0Aim
@@ -732,37 +732,28 @@
 va.lang.
-annotation.Annotation
+reflect.Type
 ;%0Aimport
@@ -952,16 +952,66 @@
  Object%3E
+ metaInfoMap;%0A%0A    public MetaInfo()%0A    %7B%0A       
  metaInf
@@ -1059,37 +1059,8 @@
 %3E();
-%0A%0A    public MetaInfo()%0A    %7B
 %0A   
@@ -1102,32 +1102,93 @@
 etaInfo )%0A    %7B%0A
+        metaInfoMap = new LinkedHashMap%3CClass%3C?%3E, Object%3E();%0A
         metaInfo
@@ -1285,18 +1285,18 @@
       if
- 
 (
+ 
 metaInfo
@@ -1317,16 +1317,17 @@
 notation
+ 
 )%0A      
@@ -1346,42 +1346,109 @@
     
-metaInfoMap.put( metaInfo.getClass
+Annotation annotation = (Annotation) metaInfo;%0A            metaInfoMap.put( annotation.annotationType
 (), 
@@ -1459,17 +1459,16 @@
 Info );%0A
-%0A
         
@@ -1468,16 +1468,24 @@
        %7D
+%0A       
  else%0A  
@@ -1484,32 +1484,105 @@
  else%0A        %7B%0A
+            Class%3C? extends Object%3E metaInfoclass = metaInfo.getClass();%0A
             Set%3C
@@ -1625,27 +1625,21 @@
 metaInfo
-.getC
+c
 lass
-()
  );%0A    

o Fix QI-73 o MetaInfo compute annotation class wrongly.