// ***************************************************************************************************************************
// * 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.juneau;

import static org.junit.Assert.*;

import java.io.*;
import java.lang.reflect.*;
import java.util.*;

import org.apache.juneau.annotation.*;
import org.apache.juneau.json.*;
import org.apache.juneau.parser.*;
import org.apache.juneau.transform.*;
import org.apache.juneau.utils.*;
import org.junit.*;

@SuppressWarnings({"unchecked","rawtypes","javadoc"})
public class BeanConfigTest {

	//====================================================================================================
	// testBasic
	//====================================================================================================
	@Test
	public void testBasic() throws Exception {

		BeanSession session = BeanContext.DEFAULT.createSession();

		Person p1 = new Person();
		p1.setName("John Doe");
		p1.setAge(25);

		Address a = new Address("101 Main St.", "Las Vegas", "NV", "89101");
		AddressablePerson p2 = new AddressablePerson();
		p2.setName("Jane Doe");
		p2.setAge(21);
		p2.setAddress(a);

		// setup the reference results
		Map m1 = new LinkedHashMap();
		m1.put("name", p1.getName());
		m1.put("age", new Integer(p1.getAge()));

		Map m2 = new LinkedHashMap();
		m2.put("street", a.getStreet());
		m2.put("city", a.getCity());
		m2.put("state", a.getState());
		m2.put("zip", a.getZip());

		Map m3 = new LinkedHashMap();
		m3.put("name", p2.getName());
		m3.put("age", new Integer(p2.getAge()));
		m3.put("address", p2.getAddress());

		Map pm1 = session.toBeanMap(p1);

		if (pm1.size() != m1.size())
			fail("Bean Map size failed for: " + p1 + " / " + pm1.size()+ " / " + m1.size());

		if (!pm1.keySet().equals(m1.keySet()))
			fail("Bean Map key set equality failed for: " + p1 + " / " + pm1.keySet() + " / " + m1.keySet());

		if (!m1.keySet().equals(pm1.keySet()))
			fail("Bean Map key set reverse equality failed for: " + p1 + " / " + pm1.keySet() + " / " + m1.keySet());

		if (!pm1.equals(m1))
			fail("Bean Map equality failed for: " + p1 + " / " + pm1 + " / " + m1);

		if (!m1.equals(pm1))
			fail("Bean Map reverse equality failed for: " + p1 + " / " + pm1 + " / " + m1);

		BeanMap bm1 = null;
		try {
			bm1 = session.newBeanMap(Address.class);
			fail("Address returned as a new bean type, but shouldn't be since it doesn't have a default constructor.");
		} catch (BeanRuntimeException e) {
			// Good.
		}
		bm1 = session.toBeanMap(new Address("street", "city", "state", "zip"));

		BeanMap bm2 = session.newBeanMap(java.lang.Integer.class);
		if (bm2 != null)
			fail("java.lang.Integer incorrectly desingated as bean type.");

		BeanMap bm3 = session.newBeanMap(java.lang.Class.class);
		if (bm3 != null)
			fail("java.lang.Class incorrectly desingated as bean type.");

		Map m4 = bm1;
		if (m4.keySet().size() != m2.size())
			fail("Bean Adapter map's key set has wrong size: " + a + " / " + m4.keySet().size() + " / " + m2.size());

		Iterator iter = m4.keySet().iterator();
		Set temp = new HashSet();
		int count = 0;
		while (iter.hasNext()) {
			temp.add(iter.next());
			count++;
		}
		if (count != m2.size())
			fail("Iteration count over bean adpater key set failed: " + a + " / " + count + " / " + m2.size());

		if (!m2.keySet().equals(temp))
			fail("Iteration over bean adpater key set failed: " + a + " / " + m4.keySet() + " / " + m2.keySet());

		BeanMap bm4 = session.toBeanMap(p2);
		if (bm4 == null) {
			fail("Failed to identify class as bean type: " + p2.getClass());
			return;
		}

		Map m5 = bm4;
		Set es1 = m5.entrySet();

		if (!es1.equals(m3.entrySet()))
			fail("Entry set equality failed: " + p2 + " / " + es1 + " / " + m3.entrySet());

		if (!m3.entrySet().equals(es1))
			fail("Entry set reverse equality failed: " + p2 + " / " + es1 + " / " + m3.entrySet());

		iter = es1.iterator();
		temp = new HashSet();
		count = 0;
		while (iter.hasNext()) {
			temp.add(iter.next());
			count++;
		}
		if (count != m3.size())
			fail("Iteration count over bean adpater entry set failed: " + a + " / " + count + " / " + m3.size());

		if (!m3.entrySet().equals(temp))
			fail("Iteration over bean adpater entry set failed: " + a + " / " + es1 + " / " + m3.entrySet());
	}

	public static class Person {
		private String name;
		private int age;

		public Person() {
			this.name = null;
			this.age = -1;
		}

		public String getName() {
			return this.name;
		}

		public void setName(String name) {
			this.name = name;
		}

		public int getAge() {
			return this.age;
		}

		public void setAge(int age) {
			this.age = age;
		}

		@Override /* Object */
		public String toString() {
			return ("Person(name: " + this.getName() + ", age: "
					+ this.getAge() + ")");
		}
	}

	public static class Address {
		protected String street;
		protected String city;
		protected String state;
		protected String zip;

		public Address(String street, String city, String state, String zip) {
			this.street = street;
			this.city = city;
			this.state = state;
			this.zip = zip;
		}

		public String getStreet() {
			return this.street;
		}

		public String getCity() {
			return this.city;
		}

		public String getState() {
			return this.state;
		}

		public String getZip() {
			return this.zip;
		}

		@Override /* Object */
		public boolean equals(Object o) {
			if (o == null)
				return false;
			if (this == o)
				return true;
			if (this.getClass() != o.getClass())
				return false;
			Address a = (Address) o;

			String v1 = this.getStreet();
			String v2 = a.getStreet();
			if ((v1 == null) ? (v2 != null) : (!v1.equals(v2)))
				return false;

			v1 = this.getCity();
			v2 = a.getCity();
			if ((v1 == null) ? (v2 != null) : (!v1.equals(v2)))
				return false;

			v1 = this.getState();
			v2 = a.getState();
			if ((v1 == null) ? (v2 != null) : (!v1.equals(v2)))
				return false;

			v1 = this.getZip();
			v2 = a.getZip();
			return ((v1 == null) ? (v2 == null) : (v1.equals(v2)));
		}

		@Override /* Object */
		public int hashCode() {
			int code = 0;
			if (this.street != null)
				code ^= this.street.hashCode();
			if (this.city != null)
				code ^= this.city.hashCode();
			if (this.state != null)
				code ^= this.state.hashCode();
			if (this.zip != null)
				code ^= this.zip.hashCode();
			return code;
		}

		@Override /* Object */
		public String toString() {
			return ("Address(street: " + this.getStreet() + ", city: "
					+ this.getCity() + ", state: " + this.getState()
					+ ", zip: " + this.getZip() + ")");
		}
	}

	public static class AddressablePerson extends Person {
		private Address address;

		public AddressablePerson() {
			this.address = null;
		}

		public Address getAddress() {
			return this.address;
		}

		public void setAddress(Address addr) {
			this.address = addr;
		}

		@Override /* Object */
		public String toString() {
			return super.toString() + "@" + this.address;
		}
	}

	//====================================================================================================
	// Exhaustive test of BeanContext.convertToType();
	//====================================================================================================
	@Test
	public void testBeanContextConvertToType() throws Exception {
		BeanSession session = BeanContext.DEFAULT.createSession();
		Object o;

		// Primitive nulls.
		o = null;
		assertEquals(new Integer(0), session.convertToType(o, Integer.TYPE));
		assertEquals(new Short((short) 0), session.convertToType(o, Short.TYPE));
		assertEquals(new Long(0), session.convertToType(o, Long.TYPE));
		assertEquals(new Float(0), session.convertToType(o, Float.TYPE));
		assertEquals(new Double(0), session.convertToType(o, Double.TYPE));
		assertEquals(new Byte((byte) 0), session.convertToType(o, Byte.TYPE));
		assertEquals(new Character((char) 0), session.convertToType(o, Character.TYPE));
		assertEquals(Boolean.FALSE, session.convertToType(o, Boolean.TYPE));

		o = "1";

		assertEquals(new Integer(1), session.convertToType(o, Integer.class));
		assertEquals(new Short((short) 1), session.convertToType(o, Short.class));
		assertEquals(new Long(1), session.convertToType(o, Long.class));
		assertEquals(new Float(1), session.convertToType(o, Float.class));
		assertEquals(new Double(1), session.convertToType(o, Double.class));
		assertEquals(new Byte((byte) 1), session.convertToType(o, Byte.class));
		assertEquals(new Character('1'), session.convertToType(o, Character.class));
		assertEquals(Boolean.FALSE, session.convertToType(o, Boolean.class));

		assertEquals(new Integer(1), session.convertToType(o, Integer.TYPE));
		assertEquals(new Short((short) 1), session.convertToType(o, Short.TYPE));
		assertEquals(new Long(1), session.convertToType(o, Long.TYPE));
		assertEquals(new Float(1), session.convertToType(o, Float.TYPE));
		assertEquals(new Double(1), session.convertToType(o, Double.TYPE));
		assertEquals(new Byte((byte) 1), session.convertToType(o, Byte.TYPE));
		assertEquals(new Character('1'), session.convertToType(o, Character.TYPE));
		assertEquals(Boolean.FALSE, session.convertToType(o, Boolean.TYPE));

		o = new Integer(1);

		assertEquals(new Integer(1), session.convertToType(o, Integer.TYPE));
		assertEquals(new Short((short) 1), session.convertToType(o, Short.TYPE));
		assertEquals(new Long(1), session.convertToType(o, Long.TYPE));
		assertEquals(new Float(1), session.convertToType(o, Float.TYPE));
		assertEquals(new Double(1), session.convertToType(o, Double.TYPE));
		assertEquals(new Byte((byte) 1), session.convertToType(o, Byte.TYPE));
		assertEquals(new Character('1'), session.convertToType(o, Character.TYPE));
		assertEquals(Boolean.TRUE, session.convertToType(o, Boolean.TYPE));

		o = new Integer(0);
		assertEquals(Boolean.FALSE, session.convertToType(o, Boolean.TYPE));

		// Bean
		o = "{name:'x',age:123}";
		assertEquals("x", session.convertToType(o, Person.class).getName());
		assertEquals(123, session.convertToType(o, Person.class).getAge());

		// Read-only bean
		o = "{name:'x',age:123}";
		assertEquals("x", session.convertToType(o, ReadOnlyPerson.class).getName());
		assertEquals(123, session.convertToType(o, ReadOnlyPerson.class).getAge());

		// Class with forString(String) method.
		o = UUID.randomUUID();
		assertEquals(o, session.convertToType(o.toString(), UUID.class));

		// Class with Constructor(String).
		o = "xxx";
		File file = session.convertToType(o, File.class);
		assertEquals("xxx", file.getName());

		// List of ints to array
		o = new ObjectList(1, 2, 3);
		assertEquals(1, session.convertToType(o, int[].class)[0]);

		// List of beans to array
		o = new ObjectList(new ReadOnlyPerson("x", 123));
		assertEquals("x", session.convertToType(o, ReadOnlyPerson[].class)[0].getName());

		// Multi-dimensional array of beans.
		o = new ObjectList().append(new ObjectList(new ReadOnlyPerson("x", 123)));
		assertEquals("x", session.convertToType(o, ReadOnlyPerson[][].class)[0][0].getName());

		// Array of strings to array of ints
		o = new String[] { "1", "2", "3" };
		assertEquals(new Integer(1), session.convertToType(o, Integer[].class)[0]);
		assertEquals(1, session.convertToType(o, int[].class)[0]);

		// Array to list
		o = new Integer[] { 1, 2, 3 };
		assertEquals(new Integer(1), session.convertToType(o, LinkedList.class).get(0));

		// HashMap to TreeMap
		o = new AMap<Integer,String>().append(1, "foo");
		assertEquals("foo", session.convertToType(o, TreeMap.class).firstEntry().getValue());

		// String to TreeMap
		o = "{1:'foo'}";
		assertEquals("foo", session.convertToType(o, TreeMap.class).firstEntry().getValue());

		// String to generic Map
		assertEquals("foo", session.convertToType(o, Map.class).values().iterator().next());

		// Array to String
		o = new Object[] { "a", 1, false };
		assertEquals("['a',1,false]", session.convertToType(o, String.class));
		o = new Object[][] { { "a", 1, false } };
		assertEquals("[['a',1,false]]", session.convertToType(o, String.class));

	}

	//====================================================================================================
	// Test properties set through a constructor.
	//====================================================================================================
	@Test
	public void testReadOnlyProperties() throws Exception {
		BeanSession session = BeanContext.DEFAULT.createSession();
		Object o;

		// Bean to String
		o = new ReadOnlyPerson("x", 123);
		assertEquals("{name:'x',age:123}", session.convertToType(o, String.class));

		// List of Maps to array of beans.
		o = new ObjectList(new ObjectMap("{name:'x',age:1}"), new ObjectMap("{name:'y',age:2}"));
		assertEquals(1, session.convertToType(o, ReadOnlyPerson[].class)[0].getAge());
	}


	@Bean(properties="name,age")
	public static class ReadOnlyPerson {
		private final String name;
		private final int age;

		@BeanConstructor(properties="name,age")
		public ReadOnlyPerson(String name, int age) {
			this.name = name;
			this.age = age;
		}

		public String getName() {
			return this.name;
		}

		public int getAge() {
			return this.age;
		}

		@Override /* Object */
		public String toString() {
			return "toString():name=" + name + ",age=" + age;
		}
	}

	//====================================================================================================
	// testEnums
	//====================================================================================================
	@Test
	public void testEnums() throws Exception {
		BeanSession session = BeanContext.DEFAULT.createSession();
		Object o;

		// Enum
		o = "ENUM2";
		assertEquals(TestEnum.ENUM2, session.convertToType(o, TestEnum.class));
		assertEquals("ENUM2", session.convertToType(TestEnum.ENUM2, String.class));

		// Array of enums
		o = new String[] { "ENUM2" };
		assertEquals(TestEnum.ENUM2, session.convertToType(o, TestEnum[].class)[0]);
	}

	public enum TestEnum {
		ENUM1, ENUM2, ENUM3
	}

	//====================================================================================================
	// testProxyHandler
	//====================================================================================================
	@Test
	public void testProxyHandler() throws Exception {
		BeanSession session = PropertyStore.create().getBeanContext().createSession();

		A f1 = (A) Proxy.newProxyInstance(this.getClass()
				.getClassLoader(), new Class[] { A.class },
				new AHandler());

		BeanMap bm1 = session.toBeanMap(f1);
		if (bm1 == null) {
			fail("Failed to obtain bean adapter for proxy: " + f1);
			return;
		}

		BeanMap bm2 = session.newBeanMap(A.class);
		if (bm2 == null) {
			fail("Failed to create dynamic proxy bean for interface: " + A.class.getName());
			return;
		}
		bm2.put("a", "Hello");
		bm2.put("b", new Integer(50));
		f1.setA("Hello");
		f1.setB(50);

		if (!bm2.get("a").equals("Hello"))
			fail("Failed to set string property 'a' on dynamic proxy bean.  " + bm2);

		if (!bm2.get("b").equals(new Integer(50)))
			fail("Failed to set string property 'b' on dynamic proxy bean.  " + bm2);

		if (!bm1.equals(bm2))
			fail("Failed equality test of dynamic proxies beans: " + bm1 + " / " + bm2);

		if (!bm2.equals(bm1))
			fail("Failed reverse equality test of dynamic proxies beans: " + bm1 + " / " + bm2);
	}

	public static interface A {
		String getA();

		void setA(String a);

		int getB();

		void setB(int b);
	}

	public static class AHandler implements InvocationHandler {
		private Map map;

		public AHandler() {
			this.map = new HashMap();
			this.map.put("a", "");
			this.map.put("b", new Integer(0));
		}

		@Override /* InvocationHandler */
		public Object invoke(Object proxy, Method method, Object[] args)
				throws Throwable {
			String methodName = method.getName();
			if (methodName.equals("getA")) {
				return this.map.get("a");
			}
			if (methodName.equals("setA")) {
				this.map.put("a", args[0]);
				return null;
			}
			if (methodName.equals("getB")) {
				return this.map.get("b");
			}
			if (methodName.equals("setB")) {
				this.map.put("b", args[0]);
				return null;
			}
			if (methodName.equals("toString")) {
				return this.map.toString();
			}
			return null;
		}
	}

	//====================================================================================================
	// testFluentStyleSetters
	//====================================================================================================
	@Test
	public void testFluentStyleSetters() throws Exception {
		B2 t = new B2().init();
		BeanMap m = BeanContext.DEFAULT.createSession().toBeanMap(t);
		m.put("f1", 2);
		assertEquals(t.f1, 2);
	}

	public static class B {
		int f1;
		public int getF1() { return f1; }
		public B setF1(int f1) { this.f1 = f1; return this; }
	}

	public static class B2 extends B {
		@Override /* B */
		public B2 setF1(int f1) { this.f1 = f1; return this; }
		public B2 init() { this.f1 = 1; return this;}
	}

	//====================================================================================================
	// testClassMetaCaching
	//====================================================================================================
	@Test
	public void testClassMetaCaching() throws Exception {
		ParserBuilder p1, p2;

		p1 = new JsonParserBuilder();
		p2 = new JsonParserBuilder();
		assertSameCache(p1, p2);

		p1.beansRequireDefaultConstructor(true);
		assertDifferentCache(p1, p2);
		p2.beansRequireDefaultConstructor(true);
		assertSameCache(p1, p2);

		p1.beansRequireSerializable(true);
		assertDifferentCache(p1, p2);
		p2.beansRequireSerializable(true);
		assertSameCache(p1, p2);

		p1.beansRequireSettersForGetters(true);
		assertDifferentCache(p1, p2);
		p2.beansRequireSettersForGetters(true);
		assertSameCache(p1, p2);

		p1.beansRequireSomeProperties(false);
		assertDifferentCache(p1, p2);
		p2.beansRequireSomeProperties(false);
		assertSameCache(p1, p2);

		p1.beanMapPutReturnsOldValue(true);
		assertDifferentCache(p1, p2);
		p2.beanMapPutReturnsOldValue(true);
		assertSameCache(p1, p2);

		p1.beanConstructorVisibility(Visibility.DEFAULT);
		assertDifferentCache(p1, p2);
		p2.beanConstructorVisibility(Visibility.DEFAULT);
		assertSameCache(p1, p2);
		p1.beanConstructorVisibility(Visibility.NONE);
		assertDifferentCache(p1, p2);
		p2.beanConstructorVisibility(Visibility.NONE);
		assertSameCache(p1, p2);
		p1.beanConstructorVisibility(Visibility.PRIVATE);
		assertDifferentCache(p1, p2);
		p2.beanConstructorVisibility(Visibility.PRIVATE);
		assertSameCache(p1, p2);
		p1.beanConstructorVisibility(Visibility.PROTECTED);
		assertDifferentCache(p1, p2);
		p2.beanConstructorVisibility(Visibility.PROTECTED);
		assertSameCache(p1, p2);

		p1.beanClassVisibility(Visibility.DEFAULT);
		assertDifferentCache(p1, p2);
		p2.beanClassVisibility(Visibility.DEFAULT);
		assertSameCache(p1, p2);
		p1.beanClassVisibility(Visibility.NONE);
		assertDifferentCache(p1, p2);
		p2.beanClassVisibility(Visibility.NONE);
		assertSameCache(p1, p2);
		p1.beanClassVisibility(Visibility.PRIVATE);
		assertDifferentCache(p1, p2);
		p2.beanClassVisibility(Visibility.PRIVATE);
		assertSameCache(p1, p2);
		p1.beanClassVisibility(Visibility.PROTECTED);
		assertDifferentCache(p1, p2);
		p2.beanClassVisibility(Visibility.PROTECTED);
		assertSameCache(p1, p2);

		p1.beanFieldVisibility(Visibility.DEFAULT);
		assertDifferentCache(p1, p2);
		p2.beanFieldVisibility(Visibility.DEFAULT);
		assertSameCache(p1, p2);
		p1.beanFieldVisibility(Visibility.NONE);
		assertDifferentCache(p1, p2);
		p2.beanFieldVisibility(Visibility.NONE);
		assertSameCache(p1, p2);
		p1.beanFieldVisibility(Visibility.PRIVATE);
		assertDifferentCache(p1, p2);
		p2.beanFieldVisibility(Visibility.PRIVATE);
		assertSameCache(p1, p2);
		p1.beanFieldVisibility(Visibility.PROTECTED);
		assertDifferentCache(p1, p2);
		p2.beanFieldVisibility(Visibility.PROTECTED);
		assertSameCache(p1, p2);

		p1.methodVisibility(Visibility.DEFAULT);
		assertDifferentCache(p1, p2);
		p2.methodVisibility(Visibility.DEFAULT);
		assertSameCache(p1, p2);
		p1.methodVisibility(Visibility.NONE);
		assertDifferentCache(p1, p2);
		p2.methodVisibility(Visibility.NONE);
		assertSameCache(p1, p2);
		p1.methodVisibility(Visibility.PRIVATE);
		assertDifferentCache(p1, p2);
		p2.methodVisibility(Visibility.PRIVATE);
		assertSameCache(p1, p2);
		p1.methodVisibility(Visibility.PROTECTED);
		assertDifferentCache(p1, p2);
		p2.methodVisibility(Visibility.PROTECTED);
		assertSameCache(p1, p2);

		p1.useJavaBeanIntrospector(true);
		assertDifferentCache(p1, p2);
		p2.useJavaBeanIntrospector(true);
		assertSameCache(p1, p2);

		p1.useInterfaceProxies(false);
		assertDifferentCache(p1, p2);
		p2.useInterfaceProxies(false);
		assertSameCache(p1, p2);

		p1.ignoreUnknownBeanProperties(true);
		assertDifferentCache(p1, p2);
		p2.ignoreUnknownBeanProperties(true);
		assertSameCache(p1, p2);

		p1.ignoreUnknownNullBeanProperties(false);
		assertDifferentCache(p1, p2);
		p2.ignoreUnknownNullBeanProperties(false);
		assertSameCache(p1, p2);

		p1.ignorePropertiesWithoutSetters(false);
		assertDifferentCache(p1, p2);
		p2.ignorePropertiesWithoutSetters(false);
		assertSameCache(p1, p2);

		p1.ignoreInvocationExceptionsOnGetters(true);
		assertDifferentCache(p1, p2);
		p2.ignoreInvocationExceptionsOnGetters(true);
		assertSameCache(p1, p2);

		p1.ignoreInvocationExceptionsOnSetters(true);
		assertDifferentCache(p1, p2);
		p2.ignoreInvocationExceptionsOnSetters(true);
		assertSameCache(p1, p2);

		p1.notBeanPackages("foo");
		assertDifferentCache(p1, p2);
		p2.notBeanPackages("foo");
		assertSameCache(p1, p2);
		p1.notBeanPackages("bar");
		assertDifferentCache(p1, p2);
		p2.notBeanPackages("bar");
		assertSameCache(p1, p2);
		p1.notBeanPackages("baz");
		p1.notBeanPackages("bing");
		assertDifferentCache(p1, p2);
		p2.notBeanPackages("bing");
		p2.notBeanPackages("baz");
		assertSameCache(p1, p2);

		p1.removeNotBeanPackages("bar");
		assertDifferentCache(p1, p2);
		p2.removeNotBeanPackages("bar");
		assertSameCache(p1, p2);

		p1.pojoSwaps(DummyPojoSwapA.class);
		assertDifferentCache(p1, p2);
		p2.pojoSwaps(DummyPojoSwapA.class);
		assertSameCache(p1, p2);
		p1.pojoSwaps(DummyPojoSwapB.class,DummyPojoSwapC.class);  // Order of filters is important!
		p2.pojoSwaps(DummyPojoSwapC.class,DummyPojoSwapB.class);
		assertDifferentCache(p1, p2);

		p1 = new JsonParserBuilder();
		p2 = new JsonParserBuilder();
		p1.beanFilters(DummyBeanFilterA.class);
		assertDifferentCache(p1, p2);
		p2.beanFilters(DummyBeanFilterA.class);
		assertSameCache(p1, p2);
		p1.beanFilters(DummyBeanFilterB.class,DummyBeanFilterC.class);  // Order of filters is important!
		p2.beanFilters(DummyBeanFilterC.class,DummyBeanFilterB.class);
		assertDifferentCache(p1, p2);
	}

	public static class DummyPojoSwapA extends MapSwap<A> {}
	public static class DummyPojoSwapB extends MapSwap<B> {}
	public static class DummyPojoSwapC extends MapSwap<C> {}
	public static class DummyBeanFilterA extends BeanFilterBuilder {
		public DummyBeanFilterA() {
			super(A.class);
		}
	}
	public static class DummyBeanFilterB extends BeanFilterBuilder {
		public DummyBeanFilterB() {
			super(B.class);
		}
	}
	public static class DummyBeanFilterC extends BeanFilterBuilder {
		public DummyBeanFilterC() {
			super(C.class);
		}
	}
	public static class C {}

	private void assertSameCache(ParserBuilder p1b, ParserBuilder p2b) {
		Parser p1 = p1b.build(), p2 = p2b.build();
		assertTrue(p1.getBeanContext().hasSameCache(p2.getBeanContext()));
		assertTrue(p1.getBeanContext().hashCode() == p2.getBeanContext().hashCode());
	}

	private void assertDifferentCache(ParserBuilder p1b, ParserBuilder p2b) {
		Parser p1 = p1b.build(), p2 = p2b.build();
		assertFalse(p1.getBeanContext().hasSameCache(p2.getBeanContext()));
		assertFalse(p1.getBeanContext().hashCode() == p2.getBeanContext().hashCode());
	}

	//====================================================================================================
	// testNotABeanReasons
	//====================================================================================================
	@Test
	public void testNotABeanNonStaticInnerClass() throws Exception {
		BeanContext bc = BeanContext.DEFAULT;
		ClassMeta cm = bc.getClassMeta(C1.class);
		assertFalse(cm.canCreateNewInstance());
	}

	public class C1 {
		public int f1;
	}

	//====================================================================================================
	// testAddingToArrayProperty
	// This tests the speed of the BeanMap.add() method against array properties.
	// For performance reasons, array properties are stored as temporary ArrayLists until the
	// BeanMap.getBean() method is called.
	//====================================================================================================
	@Test(timeout=1000) // Should be around 100ms at most.
	public void testAddingToArrayProperty() throws Exception {
		BeanSession session = BeanContext.DEFAULT.createSession();
		BeanMap<D> bm = session.newBeanMap(D.class);
		for (int i = 0; i < 5000; i++) {
			bm.add("f1", i);
			bm.add("f2", i);
			bm.add("f3", i);
			bm.add("f4", i);
		}
		D d = bm.getBean();
		assertEquals(d.f1.length, 5000);
		assertEquals(d.f2.length, 5000);
		assertEquals(d.f3.length, 5003);
		assertEquals(d.f4.length, 5003);
	}

	public class D {
		public int[] f1;
		private int[] f2;
		public int[] f3 = new int[]{1,2,3};
		private int[] f4 = new int[]{1,2,3};
		public int[] getF2() {return f2;}
		public void setF2(int[] f2) {this.f2 = f2;}
		public int[] getF4() {return f4;}
		public void setF4(int[] f4) {this.f4 = f4;}
	}

	//====================================================================================================
	// testClassClassMeta
	// Make sure we can get ClassMeta objects against the Class class.
	//====================================================================================================
	@Test
	public void testClassClassMeta() throws Exception {
		ClassMeta cm = BeanContext.DEFAULT.getClassMeta(Class.class);
		assertNotNull(cm);

		cm = BeanContext.DEFAULT.getClassMeta(Class[].class);
		assertNotNull(cm);
	}

	//====================================================================================================
	// testBlanks
	//====================================================================================================
	@Test
	public void testBlanks() throws Exception {
		BeanSession session = BeanContext.DEFAULT.createSession();

		// Blanks get interpreted as the default value for primitives and null for boxed objects.
		assertEquals(0, (int)session.convertToType("", int.class));
		assertNull(session.convertToType("", Integer.class));

		// Booleans are handled different since 'new Boolean("")' is valid and resolves to false
		// while 'new Integer("")' produces an exception.
		assertEquals(false, (boolean)session.convertToType("", boolean.class));
		assertEquals(false, session.convertToType("", Boolean.class));
	}
}