/*
 * 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 freemarker.ext.beans;

import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;

import java.lang.ref.Reference;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import freemarker.ext.beans.BeansWrapper.MethodAppearanceDecision;
import freemarker.ext.beans.BeansWrapper.MethodAppearanceDecisionInput;
import freemarker.template.Configuration;
import freemarker.template.SimpleObjectWrapper;
import freemarker.template.TemplateDateModel;
import freemarker.template.TemplateHashModel;
import freemarker.template.TemplateModelException;
import freemarker.template.TemplateScalarModel;
import freemarker.template.Version;
import freemarker.template._TemplateAPI;
import freemarker.test.utility.TestUtil;
import junit.framework.TestCase;

public class BeansWrapperSingletonsTest extends TestCase {

    public BeansWrapperSingletonsTest(String name) {
        super(name);
    }
    
    @Override
    protected void setUp() throws Exception {
        BeansWrapperBuilder.clearInstanceCache();  // otherwise ClassInrospector cache couldn't become cleared in reality
        _TemplateAPI.DefaultObjectWrapperFactory_clearInstanceCache();
        BeansWrapperBuilder.clearInstanceCache();
    }

    public void testBeansWrapperBuilderEquals() throws Exception {
        assertEquals(Configuration.VERSION_2_3_21, new BeansWrapperBuilder(Configuration.VERSION_2_3_21).getIncompatibleImprovements());
        assertEquals(Configuration.VERSION_2_3_0, new BeansWrapperBuilder(Configuration.VERSION_2_3_20).getIncompatibleImprovements());
        try {
            new BeansWrapperBuilder(TestUtil.getClosestFutureVersion());
            fail("Maybe you need to update this test for the new FreeMarker version");
        } catch (IllegalArgumentException e) {
            assertThat(e.getMessage(), containsString("upgrade"));
        }

        BeansWrapperBuilder builder1;
        BeansWrapperBuilder builder2;
        
        builder1 = new BeansWrapperBuilder(Configuration.VERSION_2_3_21);
        builder2 = new BeansWrapperBuilder(Configuration.VERSION_2_3_21);
        assertEquals(builder1, builder2);
        
        builder1.setSimpleMapWrapper(true);
        assertNotEquals(builder1, builder2);
        assertNotEquals(builder1.hashCode(), builder2.hashCode());
        builder2.setSimpleMapWrapper(true);
        assertEquals(builder1, builder2);
        assertEquals(builder1.hashCode(), builder2.hashCode());
        
        builder1.setExposeFields(true);
        assertNotEquals(builder1, builder2);
        assertNotEquals(builder1.hashCode(), builder2.hashCode());
        builder2.setExposeFields(true);
        assertEquals(builder1, builder2);
        assertEquals(builder1.hashCode(), builder2.hashCode());
        
        builder1.setExposureLevel(0);
        assertNotEquals(builder1, builder2);
        assertNotEquals(builder1.hashCode(), builder2.hashCode());
        builder2.setExposureLevel(0);
        assertEquals(builder1, builder2);
        assertEquals(builder1.hashCode(), builder2.hashCode());
        
        builder1.setExposureLevel(1);
        assertNotEquals(builder1, builder2);
        assertNotEquals(builder1.hashCode(), builder2.hashCode());
        builder2.setExposureLevel(1);
        assertEquals(builder1, builder2);
        assertEquals(builder1.hashCode(), builder2.hashCode());
        
        builder1.setDefaultDateType(TemplateDateModel.DATE);
        assertNotEquals(builder1, builder2);
        builder2.setDefaultDateType(TemplateDateModel.DATE);
        assertEquals(builder1, builder2);
        assertEquals(builder1.hashCode(), builder2.hashCode());
        
        builder1.setStrict(true);
        assertNotEquals(builder1, builder2);
        assertNotEquals(builder1.hashCode(), builder2.hashCode());
        builder2.setStrict(true);
        assertEquals(builder1, builder2);
        assertEquals(builder1.hashCode(), builder2.hashCode());

        builder1.setUseModelCache(true);
        assertNotEquals(builder1, builder2);
        assertNotEquals(builder1.hashCode(), builder2.hashCode());
        builder2.setUseModelCache(true);
        assertEquals(builder1, builder2);
        assertEquals(builder1.hashCode(), builder2.hashCode());
        
        AlphabeticalMethodSorter ms = new AlphabeticalMethodSorter(true);
        builder1.setMethodSorter(ms);
        assertNotEquals(builder1, builder2);
        builder2.setMethodSorter(ms);
        assertEquals(builder1, builder2);
        assertEquals(builder1.hashCode(), builder2.hashCode());
        
        MethodAppearanceFineTuner maft = new MethodAppearanceFineTuner() {
            public void process(MethodAppearanceDecisionInput in, MethodAppearanceDecision out) { }
        };
        builder1.setMethodAppearanceFineTuner(maft);
        assertNotEquals(builder1, builder2);
        builder2.setMethodAppearanceFineTuner(maft);
        assertEquals(builder1, builder2);
        assertEquals(builder1.hashCode(), builder2.hashCode());
        
        builder1.setTreatDefaultMethodsAsBeanMembers(true);
        assertNotEquals(builder1, builder2);
        assertNotEquals(builder1.hashCode(), builder2.hashCode());
        builder2.setTreatDefaultMethodsAsBeanMembers(true);
        assertEquals(builder1, builder2);
        assertEquals(builder1.hashCode(), builder2.hashCode());
    }
    
    public void testBeansWrapperBuilderProducts() throws Exception {
        List<BeansWrapper> hardReferences = new LinkedList<>();
        
        assertEquals(0, getBeansWrapperInstanceCacheSize());
        
        {
            BeansWrapper bw = getBeansWrapperWithSetting(Configuration.VERSION_2_3_19, true);
            assertEquals(1, getBeansWrapperInstanceCacheSize());
            assertSame(bw.getClass(), BeansWrapper.class);
            assertEquals(Configuration.VERSION_2_3_0, bw.getIncompatibleImprovements());
            assertTrue(bw.isWriteProtected());
            assertTrue(bw.isSimpleMapWrapper());
            assertTrue(bw.wrap(new HashMap()) instanceof SimpleMapModel);
            assertFalse(bw.isStrict());
            assertFalse(bw.getUseCache());
            assertEquals(TemplateDateModel.UNKNOWN, bw.getDefaultDateType());
            assertSame(bw, bw.getOuterIdentity());
            assertTrue(bw.isClassIntrospectionCacheRestricted());
            assertNull(bw.getMethodAppearanceFineTuner());
            assertNull(bw.getMethodSorter());
            
            try {
                bw.setExposeFields(true);  // can't modify the settings of a (potential) singleton
                fail();
            } catch (IllegalStateException e) {
                assertThat(e.getMessage(), containsString("modify"));
            }
            
            assertSame(bw, getBeansWrapperWithSetting(Configuration.VERSION_2_3_20, true));
            assertSame(bw, getBeansWrapperWithSetting(Configuration.VERSION_2_3_0, true));
            assertEquals(1, getBeansWrapperInstanceCacheSize());
            
            BeansWrapperBuilder factory = new BeansWrapperBuilder(new Version(2, 3, 5));
            factory.setSimpleMapWrapper(true);
            assertSame(bw, factory.build());
            assertEquals(1, getBeansWrapperInstanceCacheSize());
            
            hardReferences.add(bw);            
        }
        
        {
            BeansWrapper bw = getBeansWrapperWithSetting(Configuration.VERSION_2_3_21, true);
            assertEquals(2, getBeansWrapperInstanceCacheSize());
            assertSame(bw.getClass(), BeansWrapper.class);
            assertEquals(Configuration.VERSION_2_3_21, bw.getIncompatibleImprovements());
            assertTrue(bw.isWriteProtected());
            assertTrue(bw.isSimpleMapWrapper());
            assertTrue(bw.wrap(new HashMap()) instanceof SimpleMapModel);
            assertTrue(bw.isClassIntrospectionCacheRestricted());
            assertNull(bw.getMethodAppearanceFineTuner());
            assertNull(bw.getMethodSorter());
            
            BeansWrapperBuilder factory = new BeansWrapperBuilder(Configuration.VERSION_2_3_21);
            factory.setSimpleMapWrapper(true);
            assertSame(bw, factory.build());
            assertEquals(2, getBeansWrapperInstanceCacheSize());
            
            hardReferences.add(bw);            
        }
        
        {
            // Again... same as the very first
            BeansWrapper bw = getBeansWrapperWithSetting(Configuration.VERSION_2_3_19, true);
            assertEquals(2, getBeansWrapperInstanceCacheSize());
            assertEquals(Configuration.VERSION_2_3_0, bw.getIncompatibleImprovements());
        }
        
        {
            BeansWrapper bw = getBeansWrapperWithSetting(Configuration.VERSION_2_3_19, false);
            assertEquals(3, getBeansWrapperInstanceCacheSize());
            assertSame(bw.getClass(), BeansWrapper.class);
            assertEquals(Configuration.VERSION_2_3_0, bw.getIncompatibleImprovements());
            assertTrue(bw.isWriteProtected());
            assertFalse(bw.isSimpleMapWrapper());
            assertTrue(bw.wrap(new HashMap()) instanceof MapModel);
            
            assertSame(bw, getBeansWrapperWithSetting(Configuration.VERSION_2_3_20, false));
            assertSame(bw, getBeansWrapperWithSetting(Configuration.VERSION_2_3_0, false));
            assertSame(bw, new BeansWrapperBuilder(new Version(2, 3, 5)).build());
            assertEquals(3, getBeansWrapperInstanceCacheSize());
            
            hardReferences.add(bw);            
        }
        
        {
            BeansWrapper bw = getBeansWrapperWithSetting(Configuration.VERSION_2_3_21, false);
            assertEquals(4, getBeansWrapperInstanceCacheSize());
            assertSame(bw.getClass(), BeansWrapper.class);
            assertEquals(Configuration.VERSION_2_3_21, bw.getIncompatibleImprovements());
            assertTrue(bw.isWriteProtected());
            assertFalse(bw.isSimpleMapWrapper());
            assertTrue(bw.wrap(new HashMap()) instanceof MapModel);
            
            assertSame(bw, new BeansWrapperBuilder(Configuration.VERSION_2_3_21).build());
            assertEquals(4, getBeansWrapperInstanceCacheSize());
            
            hardReferences.add(bw);            
        }

        {
            // Again... same as earlier
            BeansWrapper bw = getBeansWrapperWithSetting(Configuration.VERSION_2_3_21, true);
            assertEquals(Configuration.VERSION_2_3_21, bw.getIncompatibleImprovements());
            assertTrue(bw.isSimpleMapWrapper());
            assertEquals(4, getBeansWrapperInstanceCacheSize());
        }
        
        {
            BeansWrapperBuilder factory = new BeansWrapperBuilder(Configuration.VERSION_2_3_19);
            factory.setExposureLevel(BeansWrapper.EXPOSE_PROPERTIES_ONLY);
            BeansWrapper bw = factory.build();
            BeansWrapper bw2 = factory.build();
            assertEquals(5, getBeansWrapperInstanceCacheSize());
            assertSame(bw, bw2);
            
            assertSame(bw.getClass(), BeansWrapper.class);
            assertEquals(Configuration.VERSION_2_3_0, bw.getIncompatibleImprovements());
            assertTrue(bw.isWriteProtected());
            assertFalse(bw.isSimpleMapWrapper());
            assertTrue(bw.wrap(new HashMap()) instanceof MapModel);
            assertEquals(BeansWrapper.EXPOSE_PROPERTIES_ONLY, bw.getExposureLevel());
            assertFalse(bw.isStrict());
            assertEquals(TemplateDateModel.UNKNOWN, bw.getDefaultDateType());
            assertSame(bw, bw.getOuterIdentity());
            
            hardReferences.add(bw);            
        }
        
        {
            BeansWrapperBuilder factory = new BeansWrapperBuilder(Configuration.VERSION_2_3_19);
            factory.setExposeFields(true);
            BeansWrapper bw = factory.build();
            BeansWrapper bw2 = factory.build();
            assertEquals(6, getBeansWrapperInstanceCacheSize());
            assertSame(bw, bw2);
            
            assertSame(bw.getClass(), BeansWrapper.class);
            assertEquals(Configuration.VERSION_2_3_0, bw.getIncompatibleImprovements());
            assertTrue(bw.isWriteProtected());
            assertFalse(bw.isSimpleMapWrapper());
            assertTrue(bw.wrap(new HashMap()) instanceof MapModel);
            assertTrue(bw.isExposeFields());
            
            hardReferences.add(bw);            
        }
        
        {
            BeansWrapperBuilder factory = new BeansWrapperBuilder(Configuration.VERSION_2_3_19);
            factory.setStrict(true);
            factory.setDefaultDateType(TemplateDateModel.DATETIME);
            factory.setOuterIdentity(new SimpleObjectWrapper());
            BeansWrapper bw = factory.build();
            assertEquals(7, getBeansWrapperInstanceCacheSize());
            assertTrue(bw.isStrict());
            assertEquals(TemplateDateModel.DATETIME, bw.getDefaultDateType());
            assertSame(SimpleObjectWrapper.class, bw.getOuterIdentity().getClass());
            
            hardReferences.add(bw);            
        }
        
        // Effect of reference and cache clearings:
        {
            BeansWrapper bw1 = new BeansWrapperBuilder(Configuration.VERSION_2_3_21).build();
            assertEquals(7, getBeansWrapperInstanceCacheSize());
            assertEquals(7, getBeansWrapperNonClearedInstanceCacheSize());
            
            clearBeansWrapperInstanceCacheReferences(false);
            assertEquals(7, getBeansWrapperInstanceCacheSize());
            assertEquals(0, getBeansWrapperNonClearedInstanceCacheSize());
            
            BeansWrapper bw2 = new BeansWrapperBuilder(Configuration.VERSION_2_3_21).build();
            assertNotSame(bw1, bw2);
            assertEquals(7, getBeansWrapperInstanceCacheSize());
            assertEquals(1, getBeansWrapperNonClearedInstanceCacheSize());
            
            assertSame(bw2, new BeansWrapperBuilder(Configuration.VERSION_2_3_21).build());
            assertEquals(1, getBeansWrapperNonClearedInstanceCacheSize());
            
            clearBeansWrapperInstanceCacheReferences(true);
            BeansWrapper bw3 = new BeansWrapperBuilder(Configuration.VERSION_2_3_21).build();
            assertNotSame(bw2, bw3);
            assertEquals(1, getBeansWrapperInstanceCacheSize());
            assertEquals(1, getBeansWrapperNonClearedInstanceCacheSize());
        }

        {
            BeansWrapperBuilder factory = new BeansWrapperBuilder(Configuration.VERSION_2_3_19);
            factory.setUseModelCache(true);
            BeansWrapper bw = factory.build();
            assertTrue(bw.getUseCache());
            assertEquals(2, getBeansWrapperInstanceCacheSize());
            
            hardReferences.add(bw);            
        }
        
        assertTrue(hardReferences.size() != 0);  // just to save it from GC until this line        
    }
    
    private BeansWrapper getBeansWrapperWithSetting(Version ici, boolean simpleMapWrapper) {
        BeansWrapperBuilder f = new BeansWrapperBuilder(ici);
        f.setSimpleMapWrapper(simpleMapWrapper);
        return f.build();
    }

    public void testMultipleTCCLs() {
        List<BeansWrapper> hardReferences = new LinkedList<>();
        
        assertEquals(0, getBeansWrapperInstanceCacheSize());
        
        BeansWrapper bw1 = new BeansWrapperBuilder(Configuration.VERSION_2_3_19).build();
        assertEquals(1, getBeansWrapperInstanceCacheSize());
        hardReferences.add(bw1);
        
        ClassLoader oldTCCL = Thread.currentThread().getContextClassLoader();
        // Doesn't mater what, just be different from oldTCCL: 
        ClassLoader newTCCL = oldTCCL == null ? this.getClass().getClassLoader() : null;
        
        BeansWrapper bw2;
        Thread.currentThread().setContextClassLoader(newTCCL);
        try {
            bw2 = new BeansWrapperBuilder(Configuration.VERSION_2_3_19).build();
            assertEquals(2, getBeansWrapperInstanceCacheSize());
            hardReferences.add(bw2);
            
            assertNotSame(bw1, bw2);
            assertSame(bw2, new BeansWrapperBuilder(Configuration.VERSION_2_3_19).build());
        } finally {
            Thread.currentThread().setContextClassLoader(oldTCCL);
        }
        
        assertSame(bw1, new BeansWrapperBuilder(Configuration.VERSION_2_3_19).build());
        assertEquals(2, getBeansWrapperInstanceCacheSize());

        BeansWrapper bw3;
        Thread.currentThread().setContextClassLoader(newTCCL);
        try {
            assertSame(bw2, new BeansWrapperBuilder(Configuration.VERSION_2_3_19).build());
            
            bw3 = new BeansWrapperBuilder(Configuration.VERSION_2_3_21).build();
            assertEquals(3, getBeansWrapperInstanceCacheSize());
            hardReferences.add(bw3);
        } finally {
            Thread.currentThread().setContextClassLoader(oldTCCL);
        }
        
        BeansWrapper bw4 = new BeansWrapperBuilder(Configuration.VERSION_2_3_21).build();
        assertEquals(4, getBeansWrapperInstanceCacheSize());
        hardReferences.add(bw4);
        
        assertNotSame(bw3, bw4);
        
        assertTrue(hardReferences.size() != 0);  // just to save it from GC until this line        
    }
    
    public void testClassInrospectorCache() throws TemplateModelException {
        assertFalse(new BeansWrapper().isClassIntrospectionCacheRestricted());
        assertFalse(new BeansWrapper(Configuration.VERSION_2_3_21).isClassIntrospectionCacheRestricted());
        assertTrue(new BeansWrapperBuilder(Configuration.VERSION_2_3_20).build().isClassIntrospectionCacheRestricted());
        
        ClassIntrospectorBuilder.clearInstanceCache();
        BeansWrapperBuilder.clearInstanceCache();
        checkClassIntrospectorCacheSize(0);
        
        List<BeansWrapper> hardReferences = new LinkedList<>();
        BeansWrapperBuilder factory;
        
        {
            factory = new BeansWrapperBuilder(Configuration.VERSION_2_3_19);
            
            BeansWrapper bw1 = factory.build();
            checkClassIntrospectorCacheSize(1);
            
            factory.setExposureLevel(BeansWrapper.EXPOSE_SAFE);  // this was already set to this
            factory.setSimpleMapWrapper(true);  // this shouldn't matter for the introspection cache
            BeansWrapper bw2 = factory.build();
            checkClassIntrospectorCacheSize(1);
            
            assertSame(bw2.getClassIntrospector(), bw1.getClassIntrospector());
            assertNotSame(bw1, bw2);
            
            // Wrapping tests:
            assertFalse(exposesFields(bw1));
            assertTrue(exposesProperties(bw1));
            assertTrue(exposesMethods(bw1));
            assertFalse(exposesUnsafe(bw1));
            assertFalse(isSimpleMapWrapper(bw1));
            assertTrue(bw1.isClassIntrospectionCacheRestricted());
            // Prevent introspection cache GC:
            hardReferences.add(bw1);
            hardReferences.add(bw2);
        }
        
        {
            factory = new BeansWrapperBuilder(Configuration.VERSION_2_3_19);
            factory.setExposeFields(true);
            BeansWrapper bw = factory.build();
            checkClassIntrospectorCacheSize(2);
            // Wrapping tests:
            assertTrue(exposesFields(bw));
            assertTrue(exposesProperties(bw));
            assertTrue(exposesMethods(bw));
            assertFalse(exposesUnsafe(bw));
            assertFalse(isSimpleMapWrapper(bw));
            // Prevent introspection cache GC:
            hardReferences.add(bw);
        }

        {
            factory.setExposureLevel(BeansWrapper.EXPOSE_ALL);
            BeansWrapper bw = factory.build();
            checkClassIntrospectorCacheSize(3);
            // Wrapping tests:
            assertTrue(exposesFields(bw));
            assertTrue(exposesProperties(bw));
            assertTrue(exposesMethods(bw));
            assertTrue(exposesUnsafe(bw));
            assertFalse(isSimpleMapWrapper(bw));
            // Prevent introspection cache GC:
            hardReferences.add(bw);
        }
        
        {
            factory.setExposeFields(false);
            BeansWrapper bw = factory.build();
            checkClassIntrospectorCacheSize(4);
            // Wrapping tests:
            assertFalse(exposesFields(bw));
            assertTrue(exposesProperties(bw));
            assertTrue(exposesMethods(bw));
            assertTrue(exposesUnsafe(bw));
            assertFalse(isSimpleMapWrapper(bw));
            // Prevent introspection cache GC:
            hardReferences.add(bw);
        }
        
        {
            factory.setExposureLevel(BeansWrapper.EXPOSE_NOTHING);
            BeansWrapper bw = factory.build();
            checkClassIntrospectorCacheSize(5);
            // Wrapping tests:
            assertFalse(exposesFields(bw));
            assertFalse(exposesProperties(bw));
            assertFalse(exposesMethods(bw));
            assertFalse(exposesUnsafe(bw));
            assertFalse(isSimpleMapWrapper(bw));
            // Prevent introspection cache GC:
            hardReferences.add(bw);
        }

        {
            factory.setExposeFields(true);
            BeansWrapper bw = factory.build();
            checkClassIntrospectorCacheSize(6);
            // Wrapping tests:
            assertTrue(exposesFields(bw));
            assertFalse(exposesProperties(bw));
            assertFalse(exposesMethods(bw));
            assertFalse(exposesUnsafe(bw));
            assertFalse(isSimpleMapWrapper(bw));
            // Prevent introspection cache GC:
            hardReferences.add(bw);
        }

        {
            factory.setExposureLevel(BeansWrapper.EXPOSE_PROPERTIES_ONLY);
            BeansWrapper bw = factory.build();
            checkClassIntrospectorCacheSize(7);
            // Wrapping tests:
            assertTrue(exposesFields(bw));
            assertTrue(exposesProperties(bw));
            assertFalse(exposesMethods(bw));
            assertFalse(exposesUnsafe(bw));
            assertFalse(isSimpleMapWrapper(bw));
            // Prevent introspection cache GC:
            hardReferences.add(bw);
        }
        
        {
            factory = new BeansWrapperBuilder(Configuration.VERSION_2_3_21);
            factory.setExposeFields(false);
            factory.setExposureLevel(BeansWrapper.EXPOSE_PROPERTIES_ONLY);
            
            BeansWrapper bw1 = factory.build();
            checkClassIntrospectorCacheSize(8);
            ClassIntrospector ci1 = bw1.getClassIntrospector();
            
            factory.setSimpleMapWrapper(true);  // Shouldn't mater
            BeansWrapper bw2 = factory.build();
            ClassIntrospector ci2 = bw2.getClassIntrospector();
            checkClassIntrospectorCacheSize(8);
            
            assertSame(ci1, ci2);
            assertNotSame(bw1, bw2);
            
            // Wrapping tests:
            assertFalse(exposesFields(bw1));
            assertTrue(exposesProperties(bw1));
            assertFalse(exposesMethods(bw1));
            assertFalse(exposesUnsafe(bw1));
            assertFalse(isSimpleMapWrapper(bw1));
            
            // Prevent introspection cache GC:
            hardReferences.add(bw1);
            hardReferences.add(bw2);
        }
        
        BeansWrapperBuilder.clearInstanceCache();  // otherwise ClassInrospector cache couldn't become cleared in reality
        _TemplateAPI.DefaultObjectWrapperFactory_clearInstanceCache();
        clearClassIntrospectorInstanceCacheReferences(false);
        checkClassIntrospectorCacheSize(8);
        assertEquals(0, getClassIntrospectorNonClearedInstanceCacheSize());

        {
            factory.setSimpleMapWrapper(false);
            factory.setExposeFields(false);
            
            BeansWrapper bw1 = factory.build();
            checkClassIntrospectorCacheSize(8);
            assertEquals(1, getClassIntrospectorNonClearedInstanceCacheSize());
            ClassIntrospector ci1 = bw1.getClassIntrospector();
            
            factory.setSimpleMapWrapper(true);  // Shouldn't mater
            BeansWrapper bw2 = factory.build();
            ClassIntrospector ci2 = bw2.getClassIntrospector();
            
            assertSame(ci1, ci2);
            assertNotSame(bw1, bw2);
            
            // Wrapping tests:
            assertFalse(exposesFields(bw1));
            assertTrue(exposesProperties(bw1));
            assertFalse(exposesMethods(bw1));
            assertFalse(exposesUnsafe(bw1));
            assertFalse(isSimpleMapWrapper(bw1));
            
            // Prevent introspection cache GC:
            hardReferences.add(bw1);
            hardReferences.add(bw2);
        }
        
        {
            factory = new BeansWrapperBuilder(Configuration.VERSION_2_3_19);
            BeansWrapper bw = factory.build();
            checkClassIntrospectorCacheSize(8);
            assertEquals(2, getClassIntrospectorNonClearedInstanceCacheSize());
            // Wrapping tests:
            assertFalse(exposesFields(bw));
            assertTrue(exposesProperties(bw));
            assertTrue(exposesMethods(bw));
            assertFalse(exposesUnsafe(bw));
            // Prevent introspection cache GC:
            hardReferences.add(bw);
        }

        clearClassIntrospectorInstanceCacheReferences(true);
        checkClassIntrospectorCacheSize(8);
        assertEquals(0, getClassIntrospectorNonClearedInstanceCacheSize());
        
        {
            factory = new BeansWrapperBuilder(Configuration.VERSION_2_3_21);
            factory.setExposeFields(true);
            BeansWrapper bw = factory.build();
            checkClassIntrospectorCacheSize(1);
            // Wrapping tests:
            assertTrue(exposesFields(bw));
            assertTrue(exposesProperties(bw));
            assertTrue(exposesMethods(bw));
            assertFalse(exposesUnsafe(bw));
            // Prevent introspection cache GC:
            hardReferences.add(bw);
        }
        
        {
            factory = new BeansWrapperBuilder(Configuration.VERSION_2_3_19);
            factory.setMethodAppearanceFineTuner(new MethodAppearanceFineTuner() {
                public void process(MethodAppearanceDecisionInput in, MethodAppearanceDecision out) {
                }
            });  // spoils ClassIntrospector() sharing
            
            BeansWrapper bw1 = factory.build();
            assertSame(bw1, factory.build());
            
            factory.setSimpleMapWrapper(true);
            BeansWrapper bw2 = factory.build();
            checkClassIntrospectorCacheSize(1);
            assertNotSame(bw1, bw2);
            assertNotSame(bw1.getClassIntrospector(), bw2.getClassIntrospector());
            assertTrue(bw1.isClassIntrospectionCacheRestricted());
            assertTrue(bw2.isClassIntrospectionCacheRestricted());
            
            // Wrapping tests:
            assertFalse(exposesFields(bw1));
            assertFalse(exposesFields(bw2));
            assertTrue(exposesProperties(bw1));
            assertTrue(exposesProperties(bw2));
            assertTrue(exposesMethods(bw1));
            assertTrue(exposesMethods(bw2));
            assertFalse(exposesUnsafe(bw1));
            assertFalse(exposesUnsafe(bw2));
            assertFalse(isSimpleMapWrapper(bw1));
            assertTrue(isSimpleMapWrapper(bw2));
        }

        {
            factory = new BeansWrapperBuilder(Configuration.VERSION_2_3_19);
            factory.setMethodAppearanceFineTuner(GetlessMethodsAsPropertyGettersRule.INSTANCE);  // doesn't spoils sharing
            
            BeansWrapper bw1 = factory.build();
            assertSame(bw1, factory.build());
            checkClassIntrospectorCacheSize(2);
            
            factory.setSimpleMapWrapper(true);
            BeansWrapper bw2 = factory.build();
            checkClassIntrospectorCacheSize(2);
            
            assertNotSame(bw1, bw2);
            assertSame(bw1.getClassIntrospector(), bw2.getClassIntrospector());  // !
            assertTrue(bw1.isClassIntrospectionCacheRestricted());
            assertTrue(bw2.isClassIntrospectionCacheRestricted());
            
            // Wrapping tests:
            assertFalse(exposesFields(bw1));
            assertFalse(exposesFields(bw2));
            assertTrue(exposesProperties(bw1));
            assertTrue(exposesProperties(bw2));
            assertTrue(exposesMethods(bw1));
            assertTrue(exposesMethods(bw2));
            assertFalse(exposesUnsafe(bw1));
            assertFalse(exposesUnsafe(bw2));
            assertFalse(isSimpleMapWrapper(bw1));
            assertTrue(isSimpleMapWrapper(bw2));
        }
        
        assertTrue(hardReferences.size() != 0);  // just to save it from GC until this line        
    }
    
    private void checkClassIntrospectorCacheSize(int expectedSize) {
        assertEquals(expectedSize, getClassIntrospectorInstanceCacheSize());
    }

    public class C {
        
        public String foo = "FOO";
        
        public String getBar() {
            return "BAR";
        }
        
    }

    private boolean isSimpleMapWrapper(BeansWrapper bw) throws TemplateModelException {
        return bw.wrap(new HashMap()) instanceof SimpleMapModel;
    }
    
    private boolean exposesFields(BeansWrapper bw) throws TemplateModelException {
        TemplateHashModel thm = (TemplateHashModel) bw.wrap(new C());
        TemplateScalarModel r = (TemplateScalarModel) thm.get("foo");
        if (r == null) return false;
        assertEquals("FOO", r.getAsString());
        return true;
    }

    private boolean exposesProperties(BeansWrapper bw) throws TemplateModelException {
        TemplateHashModel thm = (TemplateHashModel) bw.wrap(new C());
        TemplateScalarModel r = (TemplateScalarModel) thm.get("bar");
        if (r == null) return false;
        assertEquals("BAR", r.getAsString());
        return true;
    }

    private boolean exposesMethods(BeansWrapper bw) throws TemplateModelException {
        TemplateHashModel thm = (TemplateHashModel) bw.wrap(new C());
        return thm.get("getBar") != null;
    }

    private boolean exposesUnsafe(BeansWrapper bw) throws TemplateModelException {
        TemplateHashModel thm = (TemplateHashModel) bw.wrap(new C());
        return thm.get("wait") != null;
    }
    
    static int getClassIntrospectorInstanceCacheSize() {
        Map instanceCache = ClassIntrospectorBuilder.getInstanceCache();
        synchronized (instanceCache) {
            return instanceCache.size();
        }
    }

    static int getClassIntrospectorNonClearedInstanceCacheSize() {
        Map instanceCache = ClassIntrospectorBuilder.getInstanceCache();
        synchronized (instanceCache) {
            int cnt = 0;
            for (Iterator it = instanceCache.values().iterator(); it.hasNext(); ) {
                if (((Reference) it.next()).get() != null) cnt++;
            }
            return cnt;
        }
    }
    
    static void clearClassIntrospectorInstanceCacheReferences(boolean enqueue) {
        Map instanceCache = ClassIntrospectorBuilder.getInstanceCache();
        synchronized (instanceCache) {
            for (Iterator it = instanceCache.values().iterator(); it.hasNext(); ) {
                Reference ref = ((Reference) it.next());
                ref.clear();
                if (enqueue) {
                    ref.enqueue();
                }
            }
        }
    }

    static int getBeansWrapperInstanceCacheSize() {
        Map instanceCache = BeansWrapperBuilder.getInstanceCache();
        synchronized (instanceCache) {
            int size = 0; 
            for (Iterator it1 = instanceCache.values().iterator(); it1.hasNext(); ) {
                size += ((Map) it1.next()).size();
            }
            return size;
        }
    }

    static int getBeansWrapperNonClearedInstanceCacheSize() {
        Map instanceCache = BeansWrapperBuilder.getInstanceCache();
        synchronized (instanceCache) {
            int cnt = 0;
            for (Iterator it1 = instanceCache.values().iterator(); it1.hasNext(); ) {
                Map tcclScope = (Map) it1.next();
                for (Iterator it2 = tcclScope.values().iterator(); it2.hasNext(); ) {
                    if (((Reference) it2.next()).get() != null) cnt++;
                }
            }
            return cnt;
        }
    }
    
    static void clearBeansWrapperInstanceCacheReferences(boolean enqueue) {
        Map instanceCache = BeansWrapperBuilder.getInstanceCache();
        synchronized (instanceCache) {
            for (Iterator it1 = instanceCache.values().iterator(); it1.hasNext(); ) {
                Map tcclScope = (Map) it1.next();
                for (Iterator it2 = tcclScope.values().iterator(); it2.hasNext(); ) {
                    Reference ref = ((Reference) it2.next());
                    ref.clear();
                    if (enqueue) {
                        ref.enqueue();
                    }
                }
            }
        }
    }
    
}
