// 
// Decompiled by Procyon v0.6.0
// 

package org.bson.codecs.pojo;

import java.util.Iterator;
import java.util.Collection;
import java.util.ArrayList;
import org.bson.codecs.configuration.CodecRegistry;
import org.bson.codecs.Codec;
import java.util.concurrent.ConcurrentHashMap;
import java.util.List;

class PropertyCodecRegistryImpl implements PropertyCodecRegistry
{
    private final List<PropertyCodecProvider> propertyCodecProviders;
    private final ConcurrentHashMap<TypeWithTypeParameters<?>, Codec<?>> propertyCodecCache;
    
    PropertyCodecRegistryImpl(final PojoCodec<?> pojoCodec, final CodecRegistry codecRegistry, final List<PropertyCodecProvider> propertyCodecProviders) {
        final List<PropertyCodecProvider> augmentedProviders = new ArrayList<PropertyCodecProvider>();
        if (propertyCodecProviders != null) {
            augmentedProviders.addAll(propertyCodecProviders);
        }
        augmentedProviders.add(new CollectionPropertyCodecProvider());
        augmentedProviders.add(new MapPropertyCodecProvider());
        augmentedProviders.add(new EnumPropertyCodecProvider(codecRegistry));
        augmentedProviders.add(new FallbackPropertyCodecProvider(pojoCodec, codecRegistry));
        this.propertyCodecProviders = augmentedProviders;
        this.propertyCodecCache = new ConcurrentHashMap<TypeWithTypeParameters<?>, Codec<?>>();
    }
    
    @Override
    public <S> Codec<S> get(final TypeWithTypeParameters<S> typeWithTypeParameters) {
        if (this.propertyCodecCache.containsKey(typeWithTypeParameters)) {
            return (Codec)this.propertyCodecCache.get(typeWithTypeParameters);
        }
        for (final PropertyCodecProvider propertyCodecProvider : this.propertyCodecProviders) {
            final Codec<S> codec = propertyCodecProvider.get(typeWithTypeParameters, this);
            if (codec != null) {
                this.propertyCodecCache.put(typeWithTypeParameters, codec);
                return codec;
            }
        }
        return null;
    }
}
