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

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.beanutils2.priv.PrivateBeanFactory;
import org.apache.commons.beanutils2.priv.PrivateDirect;
import org.apache.commons.beanutils2.priv.PublicSubBean;

import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;

/**
 * <p>
 * Test Case for the PropertyUtils class. The majority of these tests use instances of the TestBean class, so be sure to update the tests if you change the
 * characteristics of that class.
 * </p>
 *
 * <p>
 * So far, this test case has tests for the following methods of the {@code PropertyUtils} class:
 * </p>
 * <ul>
 * <li>getIndexedProperty(Object,String)</li>
 * <li>getIndexedProperty(Object,String,int)</li>
 * <li>getMappedProperty(Object,String)</li>
 * <li>getMappedProperty(Object,String,String</li>
 * <li>getNestedProperty(Object,String)</li>
 * <li>getPropertyDescriptor(Object,String)</li>
 * <li>getPropertyDescriptors(Object)</li>
 * <li>getPropertyType(Object,String)</li>
 * <li>getSimpleProperty(Object,String)</li>
 * <li>setIndexedProperty(Object,String,Object)</li>
 * <li>setIndexedProperty(Object,String,String,Object)</li>
 * <li>setMappedProperty(Object,String,Object)</li>
 * <li>setMappedProperty(Object,String,String,Object)</li>
 * <li>setNestedProperty(Object,String,Object)</li>
 * <li>setSimpleProperty(Object,String,Object)</li>
 * </ul>
 *
 */

public class PropertyUtilsTestCase extends TestCase {

    /**
     * The fully qualified class name of our private directly implemented interface.
     */
    private static final String PRIVATE_DIRECT_CLASS = "org.apache.commons.beanutils2.priv.PrivateDirect";

    /**
     * The fully qualified class name of our private indirectly implemented interface.
     */
    private static final String PRIVATE_INDIRECT_CLASS = "org.apache.commons.beanutils2.priv.PrivateIndirect";

    /**
     * The fully qualified class name of our test bean class.
     */
    private static final String TEST_BEAN_CLASS = "org.apache.commons.beanutils2.TestBean";

    /**
     * The set of property names we expect to have returned when calling {@code getPropertyDescriptors()}. You should update this list when new properties are
     * added to TestBean.
     */
    protected final static String[] properties = { "booleanProperty", "booleanSecond", "doubleProperty", "dupProperty", "floatProperty", "intArray",
            "intIndexed", "intProperty", "listIndexed", "longProperty", "nested", "nullProperty", "readOnlyProperty", "shortProperty", "stringArray",
            "stringIndexed", "stringProperty", "writeOnlyProperty", };

    /**
     * Finds the descriptor of the name property.
     *
     * @param desc the array with descriptors
     * @return the found descriptor or null
     */
    private static PropertyDescriptor findNameDescriptor(final PropertyDescriptor[] desc) {
        for (final PropertyDescriptor element : desc) {
            if (element.getName().equals("name")) {
                return element;
            }
        }
        return null;
    }

    /**
     * Creates the tests included in this test suite.
     */
    public static Test suite() {

        return new TestSuite(PropertyUtilsTestCase.class);

    }

    /**
     * The basic test bean for each test.
     */
    protected TestBean bean = null;

    /**
     * The "package private subclass" test bean for each test.
     */
    protected TestBeanPackageSubclass beanPackageSubclass = null;

    /**
     * The test bean for private access tests.
     */
    protected PrivateDirect beanPrivate = null;

    /**
     * The test bean for private access tests of subclasses.
     */
    protected PrivateDirect beanPrivateSubclass = null;

    /**
     * The "public subclass" test bean for each test.
     */
    protected TestBeanPublicSubclass beanPublicSubclass = null;

    /**
     * The set of properties that should be described.
     */
    protected String[] describes = { "booleanProperty", "booleanSecond", "doubleProperty", "floatProperty", "intArray",
            // "intIndexed",
            "intProperty", "listIndexed", "longProperty",
            // "mappedObjects",
            // "mappedProperty",
            // "mappedIntProperty",
            "nested", "nullProperty",
            // "readOnlyProperty",
            "shortProperty", "stringArray",
            // "stringIndexed",
            "stringProperty" };

    /**
     * Constructs a new instance of this test case.
     *
     * @param name Name of the test case
     */
    public PropertyUtilsTestCase(final String name) {

        super(name);

    }

    /**
     * Returns a single string containing all the keys in the map, sorted in alphabetical order and separated by ", ".
     * <p>
     * If there are no keys, an empty string is returned.
     */
    private String keysToString(final Map<?, ?> map) {
        final Object[] mapKeys = map.keySet().toArray();
        java.util.Arrays.sort(mapKeys);
        final StringBuilder buf = new StringBuilder();
        for (int i = 0; i < mapKeys.length; ++i) {
            if (i != 0) {
                buf.append(", ");
            }
            buf.append(mapKeys[i]);
        }
        return buf.toString();
    }

    /**
     * Sets up instance variables required by this test case.
     */
    @Override
    public void setUp() {

        bean = new TestBean();
        beanPackageSubclass = new TestBeanPackageSubclass();
        beanPrivate = PrivateBeanFactory.create();
        beanPrivateSubclass = PrivateBeanFactory.createSubclass();
        beanPublicSubclass = new TestBeanPublicSubclass();

        final DynaProperty[] properties = { new DynaProperty("stringProperty", String.class), new DynaProperty("nestedBean", TestBean.class),
                new DynaProperty("nullDynaBean", DynaBean.class) };
        final BasicDynaClass dynaClass = new BasicDynaClass("nestedDynaBean", BasicDynaBean.class, properties);
        final BasicDynaBean nestedDynaBean = new BasicDynaBean(dynaClass);
        nestedDynaBean.set("nestedBean", bean);
        bean.setNestedDynaBean(nestedDynaBean);
        PropertyUtils.clearDescriptors();
    }

    /**
     * Tear down instance variables required by this test case.
     */
    @Override
    public void tearDown() {

        bean = null;
        beanPackageSubclass = null;
        beanPrivate = null;
        beanPrivateSubclass = null;
        beanPublicSubclass = null;

        PropertyUtils.resetBeanIntrospectors();
    }

    /**
     * Tries to add a null BeanIntrospector.
     */
    public void testAddBeanIntrospectorNull() {
        try {
            PropertyUtils.addBeanIntrospector(null);
            fail("Could add null BeanIntrospector!");
        } catch (final IllegalArgumentException iex) {
            // ok
        }
    }

    /**
     * Test copyProperties() when the origin is a {@code Map}.
     */
    public void testCopyPropertiesMap() {

        final Map<String, Object> map = new HashMap<>();
        map.put("booleanProperty", Boolean.FALSE);
        map.put("doubleProperty", Double.valueOf(333.0));
        map.put("dupProperty", new String[] { "New 0", "New 1", "New 2" });
        map.put("floatProperty", Float.valueOf((float) 222.0));
        map.put("intArray", new int[] { 0, 100, 200 });
        map.put("intProperty", Integer.valueOf(111));
        map.put("longProperty", Long.valueOf(444));
        map.put("shortProperty", Short.valueOf((short) 555));
        map.put("stringProperty", "New String Property");

        try {
            PropertyUtils.copyProperties(bean, map);
        } catch (final Throwable t) {
            fail("Threw " + t.toString());
        }

        // Scalar properties
        assertEquals("booleanProperty", false, bean.getBooleanProperty());
        assertEquals("doubleProperty", 333.0, bean.getDoubleProperty(), 0.005);
        assertEquals("floatProperty", (float) 222.0, bean.getFloatProperty(), (float) 0.005);
        assertEquals("intProperty", 111, bean.getIntProperty());
        assertEquals("longProperty", 444, bean.getLongProperty());
        assertEquals("shortProperty", (short) 555, bean.getShortProperty());
        assertEquals("stringProperty", "New String Property", bean.getStringProperty());

        // Indexed Properties
        final String[] dupProperty = bean.getDupProperty();
        assertNotNull("dupProperty present", dupProperty);
        assertEquals("dupProperty length", 3, dupProperty.length);
        assertEquals("dupProperty[0]", "New 0", dupProperty[0]);
        assertEquals("dupProperty[1]", "New 1", dupProperty[1]);
        assertEquals("dupProperty[2]", "New 2", dupProperty[2]);
        final int[] intArray = bean.getIntArray();
        assertNotNull("intArray present", intArray);
        assertEquals("intArray length", 3, intArray.length);
        assertEquals("intArray[0]", 0, intArray[0]);
        assertEquals("intArray[1]", 100, intArray[1]);
        assertEquals("intArray[2]", 200, intArray[2]);

    }

    /**
     * Tests whether the default introspection mechanism can be replaced by a custom BeanIntrospector.
     */
    public void testCustomIntrospection() {
        final PropertyDescriptor[] desc1 = PropertyUtils.getPropertyDescriptors(AlphaBean.class);
        PropertyDescriptor nameDescriptor = findNameDescriptor(desc1);
        assertNotNull("No write method", nameDescriptor.getWriteMethod());

        final BeanIntrospector bi = icontext -> {
            final Set<String> names = icontext.propertyNames();
            final PropertyDescriptor[] newDescs = new PropertyDescriptor[names.size()];
            int idx = 0;
            for (final Iterator<String> it = names.iterator(); it.hasNext(); idx++) {
                final String propName = it.next();
                final PropertyDescriptor pd = icontext.getPropertyDescriptor(propName);
                newDescs[idx] = new PropertyDescriptor(pd.getName(), pd.getReadMethod(), null);
            }
            icontext.addPropertyDescriptors(newDescs);
        };
        PropertyUtils.clearDescriptors();
        PropertyUtils.addBeanIntrospector(bi);
        final PropertyDescriptor[] desc2 = PropertyUtils.getPropertyDescriptors(AlphaBean.class);
        assertEquals("Different number of properties", desc1.length, desc2.length);
        nameDescriptor = findNameDescriptor(desc2);
        assertNull("Got a write method", nameDescriptor.getWriteMethod());
        PropertyUtils.removeBeanIntrospector(bi);
    }

    /**
     * Tests whether exceptions during custom introspection are handled.
     */
    public void testCustomIntrospectionEx() {
        final BeanIntrospector bi = icontext -> {
            throw new IntrospectionException("TestException");
        };
        PropertyUtils.clearDescriptors();
        PropertyUtils.addBeanIntrospector(bi);
        final PropertyDescriptor[] desc = PropertyUtils.getPropertyDescriptors(AlphaBean.class);
        assertNotNull("Introspection did not work", findNameDescriptor(desc));
        PropertyUtils.removeBeanIntrospector(bi);
    }

    /**
     * Test the describe() method.
     */
    public void testDescribe() {

        Map<String, Object> map = null;
        try {
            map = PropertyUtils.describe(bean);
        } catch (final Exception e) {
            fail("Threw exception " + e);
        }

        // Verify existence of all the properties that should be present
        for (final String describe : describes) {
            assertTrue("Property '" + describe + "' is present", map.containsKey(describe));
        }
        assertTrue("Property 'writeOnlyProperty' is not present", !map.containsKey("writeOnlyProperty"));

        // Verify the values of scalar properties
        assertEquals("Value of 'booleanProperty'", Boolean.TRUE, map.get("booleanProperty"));
        assertEquals("Value of 'doubleProperty'", Double.valueOf(321.0), map.get("doubleProperty"));
        assertEquals("Value of 'floatProperty'", Float.valueOf((float) 123.0), map.get("floatProperty"));
        assertEquals("Value of 'intProperty'", Integer.valueOf(123), map.get("intProperty"));
        assertEquals("Value of 'longProperty'", Long.valueOf(321), map.get("longProperty"));
        assertEquals("Value of 'shortProperty'", Short.valueOf((short) 987), map.get("shortProperty"));
        assertEquals("Value of 'stringProperty'", "This is a string", (String) map.get("stringProperty"));

    }

    /**
     * Test {@link PropertyUtilsBean}'s invoke method throwing an IllegalArgumentException and check that the "cause" has been properly initialized for JDK 1.4+
     * See BEANUTILS-266 for changes and reason for test
     */
    public void testExceptionFromInvoke() throws Exception {
        if (BeanUtilsBeanTestCase.isPre14JVM()) {
            return;
        }
        try {
            PropertyUtils.setSimpleProperty(bean, "intProperty", "XXX");
        } catch (final IllegalArgumentException t) {
            final Throwable cause = (Throwable) PropertyUtils.getProperty(t, "cause");
            assertNotNull("Cause not found", cause);
            assertTrue("Expected cause to be IllegalArgumentException, but was: " + cause.getClass(), cause instanceof IllegalArgumentException);
            // JDK 1.6 doesn't have "argument type mismatch" message
            // assertEquals("Check error message", "argument type mismatch", cause.getMessage());
        } catch (final Throwable t) {
            fail("Expected IllegalArgumentException, but threw " + t);
        }
    }

    /**
     * Corner cases on getPropertyDescriptor invalid arguments.
     */
    public void testGetDescriptorArguments() {

        try {
            PropertyUtils.getPropertyDescriptor(null, "stringProperty");
            fail("Should throw IllegalArgumentException 1");
        } catch (final IllegalArgumentException e) {
            // Expected response
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of IllegalArgumentException 1");
        }

        try {
            PropertyUtils.getPropertyDescriptor(bean, null);
            fail("Should throw IllegalArgumentException 2");
        } catch (final IllegalArgumentException e) {
            // Expected response
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of IllegalArgumentException 2");
        }

    }

    /**
     * Base for testGetDescriptorXxxxx() series of tests.
     *
     * @param name  Name of the property to be retrieved
     * @param read  Expected name of the read method (or null)
     * @param write Expected name of the write method (or null)
     */
    protected void testGetDescriptorBase(final String name, final String read, final String write) {

        try {
            final PropertyDescriptor pd = PropertyUtils.getPropertyDescriptor(bean, name);
            if (read == null && write == null) {
                assertNull("Got descriptor", pd);
                return;
            }
            assertNotNull("Got descriptor", pd);
            final Method rm = pd.getReadMethod();
            if (read != null) {
                assertNotNull("Got read method", rm);
                assertEquals("Got correct read method", rm.getName(), read);
            } else {
                assertNull("Got read method", rm);
            }
            final Method wm = pd.getWriteMethod();
            if (write != null) {
                assertNotNull("Got write method", wm);
                assertEquals("Got correct write method", wm.getName(), write);
            } else {
                assertNull("Got write method", wm);
            }
        } catch (final IllegalAccessException e) {
            fail("IllegalAccessException");
        } catch (final InvocationTargetException e) {
            fail("InvocationTargetException");
        } catch (final NoSuchMethodException e) {
            fail("NoSuchMethodException");
        }

    }

    /**
     * Positive getPropertyDescriptor on property {@code booleanProperty}.
     */
    public void testGetDescriptorBoolean() {

        testGetDescriptorBase("booleanProperty", "getBooleanProperty", "setBooleanProperty");

    }

    /**
     * Positive getPropertyDescriptor on property {@code doubleProperty}.
     */
    public void testGetDescriptorDouble() {

        testGetDescriptorBase("doubleProperty", "getDoubleProperty", "setDoubleProperty");

    }

    /**
     * Positive getPropertyDescriptor on property {@code floatProperty}.
     */
    public void testGetDescriptorFloat() {

        testGetDescriptorBase("floatProperty", "getFloatProperty", "setFloatProperty");

    }

    /**
     * Positive getPropertyDescriptor on property {@code intProperty}.
     */
    public void testGetDescriptorInt() {

        testGetDescriptorBase("intProperty", "getIntProperty", "setIntProperty");

    }

    /**
     * <p>
     * Negative tests on an invalid property with two different boolean getters (which is fine, according to the JavaBeans spec) but a String setter instead of
     * a boolean setter.
     * </p>
     *
     * <p>
     * Although one could logically argue that this combination of method signatures should not identify a property at all, there is a sentence in Section 8.3.1
     * making it clear that the behavior tested for here is correct: "If we find only one of these methods, then we regard it as defining either a read-only or
     * write-only property called <em>&lt;property-name&gt;</em>.
     * </p>
     */
    public void testGetDescriptorInvalidBoolean() throws Exception {

        final PropertyDescriptor pd = PropertyUtils.getPropertyDescriptor(bean, "invalidBoolean");
        assertNotNull("invalidBoolean is a property", pd);
        assertNotNull("invalidBoolean has a getter method", pd.getReadMethod());
        assertNull("invalidBoolean has no write method", pd.getWriteMethod());
        assertTrue("invalidBoolean getter method is isInvalidBoolean or getInvalidBoolean",
                Arrays.asList("isInvalidBoolean", "getInvalidBoolean").contains(pd.getReadMethod().getName()));
    }

    /**
     * Positive getPropertyDescriptor on property {@code longProperty}.
     */
    public void testGetDescriptorLong() {

        testGetDescriptorBase("longProperty", "getLongProperty", "setLongProperty");

    }

    /**
     * Test getting mapped descriptor with periods in the key.
     */
    public void testGetDescriptorMappedPeriods() {

        bean.getMappedIntProperty("xyz"); // initializes mappedIntProperty

        PropertyDescriptor desc;
        final Integer testIntegerValue = Integer.valueOf(1234);

        bean.setMappedIntProperty("key.with.a.dot", testIntegerValue.intValue());
        assertEquals("Can retrieve directly", testIntegerValue, Integer.valueOf(bean.getMappedIntProperty("key.with.a.dot")));
        try {
            desc = PropertyUtils.getPropertyDescriptor(bean, "mappedIntProperty(key.with.a.dot)");
            assertEquals("Check descriptor type (A)", Integer.TYPE, ((MappedPropertyDescriptor) desc).getMappedPropertyType());
        } catch (final Exception e) {
            fail("Threw exception (A): " + e);
        }

        bean.setMappedObjects("nested.property", new TestBean(testIntegerValue.intValue()));
        assertEquals("Can retrieve directly", testIntegerValue, Integer.valueOf(((TestBean) bean.getMappedObjects("nested.property")).getIntProperty()));
        try {
            desc = PropertyUtils.getPropertyDescriptor(bean, "mappedObjects(nested.property).intProperty");
            assertEquals("Check descriptor type (B)", Integer.TYPE, desc.getPropertyType());
        } catch (final Exception e) {
            fail("Threw exception (B): " + e);
        }
    }

    /**
     * Positive getPropertyDescriptor on property {@code readOnlyProperty}.
     */
    public void testGetDescriptorReadOnly() {

        testGetDescriptorBase("readOnlyProperty", "getReadOnlyProperty", null);

    }

    /**
     * Positive test for getPropertyDescriptors(). Each property name listed in {@code properties} should be returned exactly once.
     */
    public void testGetDescriptors() {

        final PropertyDescriptor[] pd = PropertyUtils.getPropertyDescriptors(bean);
        assertNotNull("Got descriptors", pd);
        final int[] count = new int[properties.length];
        for (final PropertyDescriptor element : pd) {
            final String name = element.getName();
            for (int j = 0; j < properties.length; j++) {
                if (name.equals(properties[j])) {
                    count[j]++;
                }
            }
        }
        for (int j = 0; j < properties.length; j++) {
            if (count[j] < 0) {
                fail("Missing property " + properties[j]);
            } else if (count[j] > 1) {
                fail("Duplicate property " + properties[j]);
            }
        }

    }

    /**
     * Corner cases on getPropertyDescriptors invalid arguments.
     */
    public void testGetDescriptorsArguments() {

        try {
            PropertyUtils.getPropertyDescriptors(null);
            fail("Should throw IllegalArgumentException");
        } catch (final IllegalArgumentException e) {
            // Expected response
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of IllegalArgumentException");
        }

    }

    /**
     * Positive getPropertyDescriptor on property {@code booleanSecond} that uses an "is" method as the getter.
     */
    public void testGetDescriptorSecond() {

        testGetDescriptorBase("booleanSecond", "isBooleanSecond", "setBooleanSecond");

    }

    /**
     * Positive getPropertyDescriptor on property {@code shortProperty}.
     */
    public void testGetDescriptorShort() {

        testGetDescriptorBase("shortProperty", "getShortProperty", "setShortProperty");

    }

    /**
     * Positive getPropertyDescriptor on property {@code stringProperty}.
     */
    public void testGetDescriptorString() {

        testGetDescriptorBase("stringProperty", "getStringProperty", "setStringProperty");

    }

    /**
     * Negative getPropertyDescriptor on property {@code unknown}.
     */
    public void testGetDescriptorUnknown() {

        testGetDescriptorBase("unknown", null, null);

    }

    /**
     * Positive getPropertyDescriptor on property {@code writeOnlyProperty}.
     */
    public void testGetDescriptorWriteOnly() {

        testGetDescriptorBase("writeOnlyProperty", null, "setWriteOnlyProperty");

    }

    /**
     * Corner cases on getIndexedProperty invalid arguments.
     */
    public void testGetIndexedArguments() {

        // Use explicit index argument

        try {
            PropertyUtils.getIndexedProperty(null, "intArray", 0);
            fail("Should throw IllegalArgumentException 1");
        } catch (final IllegalArgumentException e) {
            // Expected response
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of IllegalArgumentException 1");
        }

        try {
            PropertyUtils.getIndexedProperty(bean, null, 0);
            fail("Should throw IllegalArgumentException 2");
        } catch (final IllegalArgumentException e) {
            // Expected response
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of IllegalArgumentException 2");
        }

        // Use index expression

        try {
            PropertyUtils.getIndexedProperty(null, "intArray[0]");
            fail("Should throw IllegalArgumentException 3");
        } catch (final IllegalArgumentException e) {
            // Expected response
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of IllegalArgumentException 3");
        }

        try {
            PropertyUtils.getIndexedProperty(bean, "[0]");
            fail("Should throw NoSuchMethodException 4");
        } catch (final NoSuchMethodException e) {
            // Expected response
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of NoSuchMethodException 4");
        }

        try {
            PropertyUtils.getIndexedProperty(bean, "intArray");
            fail("Should throw IllegalArgumentException 5");
        } catch (final IllegalArgumentException e) {
            // Expected response
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of IllegalArgumentException 5");
        }

        // Use explicit index argument

        try {
            PropertyUtils.getIndexedProperty(null, "intIndexed", 0);
            fail("Should throw IllegalArgumentException 1");
        } catch (final IllegalArgumentException e) {
            // Expected response
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of IllegalArgumentException 1");
        }

        try {
            PropertyUtils.getIndexedProperty(bean, null, 0);
            fail("Should throw IllegalArgumentException 2");
        } catch (final IllegalArgumentException e) {
            // Expected response
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of IllegalArgumentException 2");
        }

        // Use index expression

        try {
            PropertyUtils.getIndexedProperty(null, "intIndexed[0]");
            fail("Should throw IllegalArgumentException 3");
        } catch (final IllegalArgumentException e) {
            // Expected response
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of IllegalArgumentException 3");
        }

        try {
            PropertyUtils.getIndexedProperty(bean, "[0]");
            fail("Should throw NoSuchMethodException 4");
        } catch (final NoSuchMethodException e) {
            // Expected response
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of NoSuchMethodException 4");
        }

        try {
            PropertyUtils.getIndexedProperty(bean, "intIndexed");
            fail("Should throw IllegalArgumentException 5");
        } catch (final IllegalArgumentException e) {
            // Expected response
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of IllegalArgumentException 5");
        }

    }

    /**
     * Test getting an indexed value out of a multi-dimensional array
     */
    public void testGetIndexedArray() {
        final String[] firstArray = { "FIRST-1", "FIRST-2", "FIRST-3" };
        final String[] secondArray = { "SECOND-1", "SECOND-2", "SECOND-3", "SECOND-4" };
        final String[][] mainArray = { firstArray, secondArray };
        final TestBean bean = new TestBean(mainArray);
        try {
            assertEquals("firstArray[0]", firstArray[0], PropertyUtils.getProperty(bean, "string2dArray[0][0]"));
            assertEquals("firstArray[1]", firstArray[1], PropertyUtils.getProperty(bean, "string2dArray[0][1]"));
            assertEquals("firstArray[2]", firstArray[2], PropertyUtils.getProperty(bean, "string2dArray[0][2]"));
            assertEquals("secondArray[0]", secondArray[0], PropertyUtils.getProperty(bean, "string2dArray[1][0]"));
            assertEquals("secondArray[1]", secondArray[1], PropertyUtils.getProperty(bean, "string2dArray[1][1]"));
            assertEquals("secondArray[2]", secondArray[2], PropertyUtils.getProperty(bean, "string2dArray[1][2]"));
            assertEquals("secondArray[3]", secondArray[3], PropertyUtils.getProperty(bean, "string2dArray[1][3]"));
        } catch (final Throwable t) {
            fail("Threw " + t + "");
        }
    }

    /**
     * Test getting an indexed value out of List of Lists
     */
    public void testGetIndexedList() {
        final String[] firstArray = { "FIRST-1", "FIRST-2", "FIRST-3" };
        final String[] secondArray = { "SECOND-1", "SECOND-2", "SECOND-3", "SECOND-4" };
        final List<Object> mainList = new ArrayList<>();
        mainList.add(Arrays.asList(firstArray));
        mainList.add(Arrays.asList(secondArray));
        final TestBean bean = new TestBean(mainList);
        try {
            assertEquals("firstArray[0]", firstArray[0], PropertyUtils.getProperty(bean, "listIndexed[0][0]"));
            assertEquals("firstArray[1]", firstArray[1], PropertyUtils.getProperty(bean, "listIndexed[0][1]"));
            assertEquals("firstArray[2]", firstArray[2], PropertyUtils.getProperty(bean, "listIndexed[0][2]"));
            assertEquals("secondArray[0]", secondArray[0], PropertyUtils.getProperty(bean, "listIndexed[1][0]"));
            assertEquals("secondArray[1]", secondArray[1], PropertyUtils.getProperty(bean, "listIndexed[1][1]"));
            assertEquals("secondArray[2]", secondArray[2], PropertyUtils.getProperty(bean, "listIndexed[1][2]"));
            assertEquals("secondArray[3]", secondArray[3], PropertyUtils.getProperty(bean, "listIndexed[1][3]"));
        } catch (final Throwable t) {
            fail("Threw " + t + "");
        }
    }

    /**
     * Test getting a value out of a mapped Map
     */
    public void testGetIndexedMap() {
        final Map<String, Object> firstMap = new HashMap<>();
        firstMap.put("FIRST-KEY-1", "FIRST-VALUE-1");
        firstMap.put("FIRST-KEY-2", "FIRST-VALUE-2");
        final Map<String, Object> secondMap = new HashMap<>();
        secondMap.put("SECOND-KEY-1", "SECOND-VALUE-1");
        secondMap.put("SECOND-KEY-2", "SECOND-VALUE-2");

        final List<Object> mainList = new ArrayList<>();
        mainList.add(firstMap);
        mainList.add(secondMap);
        final TestBean bean = new TestBean(mainList);
        try {
            assertEquals("listIndexed[0](FIRST-KEY-1)", "FIRST-VALUE-1", PropertyUtils.getProperty(bean, "listIndexed[0](FIRST-KEY-1)"));
            assertEquals("listIndexed[0](FIRST-KEY-2)", "FIRST-VALUE-2", PropertyUtils.getProperty(bean, "listIndexed[0](FIRST-KEY-2)"));
            assertEquals("listIndexed[1](SECOND-KEY-1)", "SECOND-VALUE-1", PropertyUtils.getProperty(bean, "listIndexed[1](SECOND-KEY-1)"));
            assertEquals("listIndexed[1](SECOND-KEY-2)", "SECOND-VALUE-2", PropertyUtils.getProperty(bean, "listIndexed[1](SECOND-KEY-2)"));
        } catch (final Throwable t) {
            fail("Threw " + t + "");
        }
    }

    /**
     * Positive and negative tests on getIndexedProperty valid arguments.
     */
    public void testGetIndexedValues() {

        Object value = null;

        // Use explicit key argument

        for (int i = 0; i < 5; i++) {

            try {
                value = PropertyUtils.getIndexedProperty(bean, "dupProperty", i);
                assertNotNull("dupProperty returned value " + i, value);
                assertTrue("dupProperty returned String " + i, value instanceof String);
                assertEquals("dupProperty returned correct " + i, "Dup " + i, (String) value);
            } catch (final Throwable t) {
                fail("dupProperty " + i + " threw " + t);
            }

            try {
                value = PropertyUtils.getIndexedProperty(bean, "intArray", i);
                assertNotNull("intArray returned value " + i, value);
                assertTrue("intArray returned Integer " + i, value instanceof Integer);
                assertEquals("intArray returned correct " + i, i * 10, ((Integer) value).intValue());
            } catch (final Throwable t) {
                fail("intArray " + i + " threw " + t);
            }

            try {
                value = PropertyUtils.getIndexedProperty(bean, "intIndexed", i);
                assertNotNull("intIndexed returned value " + i, value);
                assertTrue("intIndexed returned Integer " + i, value instanceof Integer);
                assertEquals("intIndexed returned correct " + i, i * 10, ((Integer) value).intValue());
            } catch (final Throwable t) {
                fail("intIndexed " + i + " threw " + t);
            }

            try {
                value = PropertyUtils.getIndexedProperty(bean, "listIndexed", i);
                assertNotNull("listIndexed returned value " + i, value);
                assertTrue("list returned String " + i, value instanceof String);
                assertEquals("listIndexed returned correct " + i, "String " + i, (String) value);
            } catch (final Throwable t) {
                fail("listIndexed " + i + " threw " + t);
            }

            try {
                value = PropertyUtils.getIndexedProperty(bean, "stringArray", i);
                assertNotNull("stringArray returned value " + i, value);
                assertTrue("stringArray returned String " + i, value instanceof String);
                assertEquals("stringArray returned correct " + i, "String " + i, (String) value);
            } catch (final Throwable t) {
                fail("stringArray " + i + " threw " + t);
            }

            try {
                value = PropertyUtils.getIndexedProperty(bean, "stringIndexed", i);
                assertNotNull("stringIndexed returned value " + i, value);
                assertTrue("stringIndexed returned String " + i, value instanceof String);
                assertEquals("stringIndexed returned correct " + i, "String " + i, (String) value);
            } catch (final Throwable t) {
                fail("stringIndexed " + i + " threw " + t);
            }

        }

        // Use key expression

        for (int i = 0; i < 5; i++) {

            try {
                value = PropertyUtils.getIndexedProperty(bean, "dupProperty[" + i + "]");
                assertNotNull("dupProperty returned value " + i, value);
                assertTrue("dupProperty returned String " + i, value instanceof String);
                assertEquals("dupProperty returned correct " + i, "Dup " + i, (String) value);
            } catch (final Throwable t) {
                fail("dupProperty " + i + " threw " + t);
            }

            try {
                value = PropertyUtils.getIndexedProperty(bean, "intArray[" + i + "]");
                assertNotNull("intArray returned value " + i, value);
                assertTrue("intArray returned Integer " + i, value instanceof Integer);
                assertEquals("intArray returned correct " + i, i * 10, ((Integer) value).intValue());
            } catch (final Throwable t) {
                fail("intArray " + i + " threw " + t);
            }

            try {
                value = PropertyUtils.getIndexedProperty(bean, "intIndexed[" + i + "]");
                assertNotNull("intIndexed returned value " + i, value);
                assertTrue("intIndexed returned Integer " + i, value instanceof Integer);
                assertEquals("intIndexed returned correct " + i, i * 10, ((Integer) value).intValue());
            } catch (final Throwable t) {
                fail("intIndexed " + i + " threw " + t);
            }

            try {
                value = PropertyUtils.getIndexedProperty(bean, "listIndexed[" + i + "]");
                assertNotNull("listIndexed returned value " + i, value);
                assertTrue("listIndexed returned String " + i, value instanceof String);
                assertEquals("listIndexed returned correct " + i, "String " + i, (String) value);
            } catch (final Throwable t) {
                fail("listIndexed " + i + " threw " + t);
            }

            try {
                value = PropertyUtils.getIndexedProperty(bean, "stringArray[" + i + "]");
                assertNotNull("stringArray returned value " + i, value);
                assertTrue("stringArray returned String " + i, value instanceof String);
                assertEquals("stringArray returned correct " + i, "String " + i, (String) value);
            } catch (final Throwable t) {
                fail("stringArray " + i + " threw " + t);
            }

            try {
                value = PropertyUtils.getIndexedProperty(bean, "stringIndexed[" + i + "]");
                assertNotNull("stringIndexed returned value " + i, value);
                assertTrue("stringIndexed returned String " + i, value instanceof String);
                assertEquals("stringIndexed returned correct " + i, "String " + i, (String) value);
            } catch (final Throwable t) {
                fail("stringIndexed " + i + " threw " + t);
            }

        }

        // Index out of bounds tests

        try {
            value = PropertyUtils.getIndexedProperty(bean, "dupProperty", -1);
            fail("Should have thrown ArrayIndexOutOfBoundsException");
        } catch (final ArrayIndexOutOfBoundsException t) {
            // Expected results
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException");
        }

        try {
            value = PropertyUtils.getIndexedProperty(bean, "dupProperty", 5);
            fail("Should have thrown ArrayIndexOutOfBoundsException");
        } catch (final ArrayIndexOutOfBoundsException t) {
            // Expected results
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException");
        }

        try {
            value = PropertyUtils.getIndexedProperty(bean, "intArray", -1);
            fail("Should have thrown ArrayIndexOutOfBoundsException");
        } catch (final ArrayIndexOutOfBoundsException t) {
            // Expected results
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException");
        }

        try {
            value = PropertyUtils.getIndexedProperty(bean, "intArray", 5);
            fail("Should have thrown ArrayIndexOutOfBoundsException");
        } catch (final ArrayIndexOutOfBoundsException t) {
            // Expected results
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException");
        }

        try {
            value = PropertyUtils.getIndexedProperty(bean, "intIndexed", -1);
            fail("Should have thrown ArrayIndexOutOfBoundsException");
        } catch (final ArrayIndexOutOfBoundsException t) {
            // Expected results
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException");
        }

        try {
            value = PropertyUtils.getIndexedProperty(bean, "intIndexed", 5);
            fail("Should have thrown ArrayIndexOutOfBoundsException");
        } catch (final ArrayIndexOutOfBoundsException t) {
            // Expected results
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException");
        }

        try {
            value = PropertyUtils.getIndexedProperty(bean, "listIndexed", -1);
            fail("Should have thrown IndexOutOfBoundsException");
        } catch (final IndexOutOfBoundsException t) {
            // Expected results
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of IndexOutOfBoundsException");
        }

        try {
            value = PropertyUtils.getIndexedProperty(bean, "listIndexed", 5);
            fail("Should have thrown IndexOutOfBoundsException");
        } catch (final IndexOutOfBoundsException t) {
            // Expected results
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of IndexOutOfBoundsException");
        }

        try {
            value = PropertyUtils.getIndexedProperty(bean, "stringArray", -1);
            fail("Should have thrown ArrayIndexOutOfBoundsException");
        } catch (final ArrayIndexOutOfBoundsException t) {
            // Expected results
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException");
        }

        try {
            value = PropertyUtils.getIndexedProperty(bean, "stringArray", 5);
            fail("Should have thrown ArrayIndexOutOfBoundsException");
        } catch (final ArrayIndexOutOfBoundsException t) {
            // Expected results
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException");
        }

        try {
            value = PropertyUtils.getIndexedProperty(bean, "stringIndexed", -1);
            fail("Should have thrown ArrayIndexOutOfBoundsException");
        } catch (final ArrayIndexOutOfBoundsException t) {
            // Expected results
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException");
        }

        try {
            value = PropertyUtils.getIndexedProperty(bean, "stringIndexed", 5);
            fail("Should have thrown ArrayIndexOutOfBoundsException");
        } catch (final ArrayIndexOutOfBoundsException t) {
            // Expected results
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException");
        }

    }

    /**
     * Corner cases on getMappedProperty invalid arguments.
     */
    public void testGetMappedArguments() {

        // Use explicit key argument

        try {
            PropertyUtils.getMappedProperty(null, "mappedProperty", "First Key");
            fail("Should throw IllegalArgumentException 1");
        } catch (final IllegalArgumentException e) {
            // Expected response
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of IllegalArgumentException 1");
        }

        try {
            PropertyUtils.getMappedProperty(bean, null, "First Key");
            fail("Should throw IllegalArgumentException 2");
        } catch (final IllegalArgumentException e) {
            // Expected response
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of IllegalArgumentException 2");
        }

        try {
            PropertyUtils.getMappedProperty(bean, "mappedProperty", null);
            fail("Should throw IllegalArgumentException 3");
        } catch (final IllegalArgumentException e) {
            // Expected response
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of IllegalArgumentException 3");
        }

        // Use key expression

        try {
            PropertyUtils.getMappedProperty(null, "mappedProperty(First Key)");
            fail("Should throw IllegalArgumentException 4");
        } catch (final IllegalArgumentException e) {
            // Expected response
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of IllegalArgumentException 4");
        }

        try {
            PropertyUtils.getMappedProperty(bean, "(Second Key)");
            fail("Should throw IllegalArgumentException 5");
        } catch (final NoSuchMethodException e) {
            // Expected response
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of NoSuchMethodException 5");
        }

        try {
            PropertyUtils.getMappedProperty(bean, "mappedProperty");
            fail("Should throw IllegalArgumentException 6");
        } catch (final IllegalArgumentException e) {
            // Expected response
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of IllegalArgumentException 6");
        }

    }

    /**
     * Test getting an indexed value out of a mapped array
     */
    public void testGetMappedArray() {
        final TestBean bean = new TestBean();
        final String[] array = { "abc", "def", "ghi" };
        bean.getMapProperty().put("mappedArray", array);
        try {
            assertEquals("abc", PropertyUtils.getProperty(bean, "mapProperty(mappedArray)[0]"));
            assertEquals("def", PropertyUtils.getProperty(bean, "mapProperty(mappedArray)[1]"));
            assertEquals("ghi", PropertyUtils.getProperty(bean, "mapProperty(mappedArray)[2]"));
        } catch (final Throwable t) {
            fail("Threw " + t + "");
        }
    }

    /**
     * Test getting an indexed value out of a mapped List
     */
    public void testGetMappedList() {
        final TestBean bean = new TestBean();
        final List<Object> list = new ArrayList<>();
        list.add("klm");
        list.add("nop");
        list.add("qrs");
        bean.getMapProperty().put("mappedList", list);
        try {
            assertEquals("klm", PropertyUtils.getProperty(bean, "mapProperty(mappedList)[0]"));
            assertEquals("nop", PropertyUtils.getProperty(bean, "mapProperty(mappedList)[1]"));
            assertEquals("qrs", PropertyUtils.getProperty(bean, "mapProperty(mappedList)[2]"));
        } catch (final Throwable t) {
            fail("Threw " + t + "");
        }
    }

    /**
     * Test getting a value out of a mapped Map
     */
    public void testGetMappedMap() {
        final TestBean bean = new TestBean();
        final Map<String, Object> map = new HashMap<>();
        map.put("sub-key-1", "sub-value-1");
        map.put("sub-key-2", "sub-value-2");
        map.put("sub-key-3", "sub-value-3");
        bean.getMapProperty().put("mappedMap", map);
        try {
            assertEquals("sub-value-1", PropertyUtils.getProperty(bean, "mapProperty(mappedMap)(sub-key-1)"));
            assertEquals("sub-value-2", PropertyUtils.getProperty(bean, "mapProperty(mappedMap)(sub-key-2)"));
            assertEquals("sub-value-3", PropertyUtils.getProperty(bean, "mapProperty(mappedMap)(sub-key-3)"));
        } catch (final Throwable t) {
            fail("Threw " + t + "");
        }
    }

    /**
     * Test getting mapped values with periods in the key.
     */
    public void testGetMappedPeriods() {

        bean.setMappedProperty("key.with.a.dot", "Special Value");
        assertEquals("Can retrieve directly", "Special Value", bean.getMappedProperty("key.with.a.dot"));
        try {
            assertEquals("Can retrieve via getMappedProperty", "Special Value", PropertyUtils.getMappedProperty(bean, "mappedProperty", "key.with.a.dot"));
        } catch (final Exception e) {
            fail("Thew exception: " + e);
        }
        try {
            assertEquals("Can retrieve via getNestedProperty", "Special Value", PropertyUtils.getNestedProperty(bean, "mappedProperty(key.with.a.dot)"));
        } catch (final Exception e) {
            fail("Thew exception: " + e);
        }

        bean.setMappedObjects("nested.property", new TestBean());
        assertNotNull("Can retrieve directly", bean.getMappedObjects("nested.property"));
        try {
            assertEquals("Can retrieve nested", "This is a string", PropertyUtils.getNestedProperty(bean, "mappedObjects(nested.property).stringProperty"));
        } catch (final Exception e) {
            fail("Thew exception: " + e);
        }

        try {
            assertEquals("Can't retrieved nested with mapped property", "Mapped Value",
                    PropertyUtils.getNestedProperty(bean, "mappedNested.value(Mapped Key)"));
        } catch (final Exception e) {
            fail("Thew exception: " + e);
        }
    }

    /**
     * Test getting mapped values with slashes in the key. This is different from periods because slashes are not syntactically significant.
     */
    public void testGetMappedSlashes() {

        bean.setMappedProperty("key/with/a/slash", "Special Value");
        assertEquals("Can retrieve directly", "Special Value", bean.getMappedProperty("key/with/a/slash"));
        try {
            assertEquals("Can retrieve via getMappedProperty", "Special Value", PropertyUtils.getMappedProperty(bean, "mappedProperty", "key/with/a/slash"));
        } catch (final Exception e) {
            fail("Thew exception: " + e);
        }
        try {
            assertEquals("Can retrieve via getNestedProperty", "Special Value", PropertyUtils.getNestedProperty(bean, "mappedProperty(key/with/a/slash)"));
        } catch (final Exception e) {
            fail("Thew exception: " + e);
        }

        bean.setMappedObjects("nested/property", new TestBean());
        assertNotNull("Can retrieve directly", bean.getMappedObjects("nested/property"));
        try {
            assertEquals("Can retrieve nested", "This is a string", PropertyUtils.getNestedProperty(bean, "mappedObjects(nested/property).stringProperty"));
        } catch (final Exception e) {
            fail("Thew exception: " + e);
        }

    }

    /**
     * Positive and negative tests on getMappedProperty valid arguments.
     */
    public void testGetMappedValues() {

        Object value = null;

        // Use explicit key argument

        try {
            value = PropertyUtils.getMappedProperty(bean, "mappedProperty", "First Key");
            assertEquals("Can find first value", "First Value", value);
        } catch (final Throwable t) {
            fail("Finding first value threw " + t);
        }

        try {
            value = PropertyUtils.getMappedProperty(bean, "mappedProperty", "Second Key");
            assertEquals("Can find second value", "Second Value", value);
        } catch (final Throwable t) {
            fail("Finding second value threw " + t);
        }

        try {
            value = PropertyUtils.getMappedProperty(bean, "mappedProperty", "Third Key");
            assertNull("Can not find third value", value);
        } catch (final Throwable t) {
            fail("Finding third value threw " + t);
        }

        // Use key expression with parentheses

        try {
            value = PropertyUtils.getMappedProperty(bean, "mappedProperty(First Key)");
            assertEquals("Can find first value", "First Value", value);
        } catch (final Throwable t) {
            fail("Finding first value threw " + t);
        }

        try {
            value = PropertyUtils.getMappedProperty(bean, "mappedProperty(Second Key)");
            assertEquals("Can find second value", "Second Value", value);
        } catch (final Throwable t) {
            fail("Finding second value threw " + t);
        }

        try {
            value = PropertyUtils.getMappedProperty(bean, "mappedProperty(Third Key)");
            assertNull("Can not find third value", value);
        } catch (final Throwable t) {
            fail("Finding third value threw " + t);
        }

        // Use key expression with dotted syntax

        try {
            value = PropertyUtils.getNestedProperty(bean, "mapProperty.First Key");
            assertEquals("Can find first value", "First Value", value);
        } catch (final Throwable t) {
            fail("Finding first value threw " + t);
        }

        try {
            value = PropertyUtils.getNestedProperty(bean, "mapProperty.Second Key");
            assertEquals("Can find second value", "Second Value", value);
        } catch (final Throwable t) {
            fail("Finding second value threw " + t);
        }

        try {
            value = PropertyUtils.getNestedProperty(bean, "mapProperty.Third Key");
            assertNull("Can not find third value", value);
        } catch (final Throwable t) {
            fail("Finding third value threw " + t);
        }

    }

    /**
     * Corner cases on getNestedProperty invalid arguments.
     */
    public void testGetNestedArguments() {

        try {
            PropertyUtils.getNestedProperty(null, "stringProperty");
            fail("Should throw IllegalArgumentException 1");
        } catch (final IllegalArgumentException e) {
            // Expected response
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of IllegalArgumentException 1");
        }

        try {
            PropertyUtils.getNestedProperty(bean, null);
            fail("Should throw IllegalArgumentException 2");
        } catch (final IllegalArgumentException e) {
            // Expected response
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of IllegalArgumentException 2");
        }

    }

    /**
     * Test getNestedProperty on a boolean property.
     */
    public void testGetNestedBoolean() {

        try {
            final Object value = PropertyUtils.getNestedProperty(bean, "nested.booleanProperty");
            assertNotNull("Got a value", value);
            assertTrue("Got correct type", value instanceof Boolean);
            assertTrue("Got correct value", ((Boolean) value).booleanValue() == bean.getNested().getBooleanProperty());
        } catch (final IllegalAccessException e) {
            fail("IllegalAccessException");
        } catch (final IllegalArgumentException e) {
            fail("IllegalArgumentException");
        } catch (final InvocationTargetException e) {
            fail("InvocationTargetException");
        } catch (final NoSuchMethodException e) {
            fail("NoSuchMethodException");
        }

    }

    /**
     * Test getNestedProperty on a double property.
     */
    public void testGetNestedDouble() {

        try {
            final Object value = PropertyUtils.getNestedProperty(bean, "nested.doubleProperty");
            assertNotNull("Got a value", value);
            assertTrue("Got correct type", value instanceof Double);
            assertEquals("Got correct value", ((Double) value).doubleValue(), bean.getNested().getDoubleProperty(), 0.005);
        } catch (final IllegalAccessException e) {
            fail("IllegalAccessException");
        } catch (final IllegalArgumentException e) {
            fail("IllegalArgumentException");
        } catch (final InvocationTargetException e) {
            fail("InvocationTargetException");
        } catch (final NoSuchMethodException e) {
            fail("NoSuchMethodException");
        }

    }

    /**
     * Test getNestedProperty on a float property.
     */
    public void testGetNestedFloat() {

        try {
            final Object value = PropertyUtils.getNestedProperty(bean, "nested.floatProperty");
            assertNotNull("Got a value", value);
            assertTrue("Got correct type", value instanceof Float);
            assertEquals("Got correct value", ((Float) value).floatValue(), bean.getNested().getFloatProperty(), (float) 0.005);
        } catch (final IllegalAccessException e) {
            fail("IllegalAccessException");
        } catch (final IllegalArgumentException e) {
            fail("IllegalArgumentException");
        } catch (final InvocationTargetException e) {
            fail("InvocationTargetException");
        } catch (final NoSuchMethodException e) {
            fail("NoSuchMethodException");
        }

    }

    /**
     * Test getNestedProperty on an int property.
     */
    public void testGetNestedInt() {

        try {
            final Object value = PropertyUtils.getNestedProperty(bean, "nested.intProperty");
            assertNotNull("Got a value", value);
            assertTrue("Got correct type", value instanceof Integer);
            assertEquals("Got correct value", ((Integer) value).intValue(), bean.getNested().getIntProperty());
        } catch (final IllegalAccessException e) {
            fail("IllegalAccessException");
        } catch (final IllegalArgumentException e) {
            fail("IllegalArgumentException");
        } catch (final InvocationTargetException e) {
            fail("InvocationTargetException");
        } catch (final NoSuchMethodException e) {
            fail("NoSuchMethodException");
        }

    }

    /**
     * Test getNestedProperty on a long property.
     */
    public void testGetNestedLong() {

        try {
            final Object value = PropertyUtils.getNestedProperty(bean, "nested.longProperty");
            assertNotNull("Got a value", value);
            assertTrue("Got correct type", value instanceof Long);
            assertEquals("Got correct value", ((Long) value).longValue(), bean.getNested().getLongProperty());
        } catch (final IllegalAccessException e) {
            fail("IllegalAccessException");
        } catch (final IllegalArgumentException e) {
            fail("IllegalArgumentException");
        } catch (final InvocationTargetException e) {
            fail("InvocationTargetException");
        } catch (final NoSuchMethodException e) {
            fail("NoSuchMethodException");
        }

    }

    /**
     * Test getNestedProperty on a read-only String property.
     */
    public void testGetNestedReadOnly() {

        try {
            final Object value = PropertyUtils.getNestedProperty(bean, "nested.readOnlyProperty");
            assertNotNull("Got a value", value);
            assertTrue("Got correct type", value instanceof String);
            assertEquals("Got correct value", (String) value, bean.getReadOnlyProperty());
        } catch (final IllegalAccessException e) {
            fail("IllegalAccessException");
        } catch (final IllegalArgumentException e) {
            fail("IllegalArgumentException");
        } catch (final InvocationTargetException e) {
            fail("InvocationTargetException");
        } catch (final NoSuchMethodException e) {
            fail("NoSuchMethodException");
        }

    }

    /**
     * Test getNestedProperty on a short property.
     */
    public void testGetNestedShort() {

        try {
            final Object value = PropertyUtils.getNestedProperty(bean, "nested.shortProperty");
            assertNotNull("Got a value", value);
            assertTrue("Got correct type", value instanceof Short);
            assertEquals("Got correct value", ((Short) value).shortValue(), bean.getNested().getShortProperty());
        } catch (final IllegalAccessException e) {
            fail("IllegalAccessException");
        } catch (final IllegalArgumentException e) {
            fail("IllegalArgumentException");
        } catch (final InvocationTargetException e) {
            fail("InvocationTargetException");
        } catch (final NoSuchMethodException e) {
            fail("NoSuchMethodException");
        }

    }

    /**
     * Test getNestedProperty on a String property.
     */
    public void testGetNestedString() {

        try {
            final Object value = PropertyUtils.getNestedProperty(bean, "nested.stringProperty");
            assertNotNull("Got a value", value);
            assertTrue("Got correct type", value instanceof String);
            assertEquals("Got correct value", (String) value, bean.getNested().getStringProperty());
        } catch (final IllegalAccessException e) {
            fail("IllegalAccessException");
        } catch (final IllegalArgumentException e) {
            fail("IllegalArgumentException");
        } catch (final InvocationTargetException e) {
            fail("InvocationTargetException");
        } catch (final NoSuchMethodException e) {
            fail("NoSuchMethodException");
        }

    }

    /**
     * Negative test getNestedProperty on an unknown property.
     */
    public void testGetNestedUnknown() {

        try {
            PropertyUtils.getNestedProperty(bean, "nested.unknown");
            fail("Should have thrown NoSuchMethodException");
        } catch (final IllegalAccessException e) {
            fail("IllegalAccessException");
        } catch (final IllegalArgumentException e) {
            fail("IllegalArgumentException");
        } catch (final InvocationTargetException e) {
            fail("InvocationTargetException");
        } catch (final NoSuchMethodException e) {
            // Correct result for this test
        }

    }

    /**
     * Test getNestedProperty on a write-only String property.
     */
    public void testGetNestedWriteOnly() {

        try {
            PropertyUtils.getNestedProperty(bean, "writeOnlyProperty");
            fail("Should have thrown NoSuchMethodException");
        } catch (final IllegalAccessException e) {
            fail("IllegalAccessException");
        } catch (final IllegalArgumentException e) {
            fail("IllegalArgumentException");
        } catch (final InvocationTargetException e) {
            fail("InvocationTargetException");
        } catch (final NoSuchMethodException e) {
            // Correct result for this test
        }

    }

    /**
     * Test getPropertyType() on all kinds of properties.
     */
    public void testGetPropertyType() {

        Class<?> clazz = null;
        final int[] intArray = {};
        final String[] stringArray = {};

        try {

            // Scalar and Indexed Properties
            clazz = PropertyUtils.getPropertyType(bean, "booleanProperty");
            assertEquals("booleanProperty type", Boolean.TYPE, clazz);
            clazz = PropertyUtils.getPropertyType(bean, "booleanSecond");
            assertEquals("booleanSecond type", Boolean.TYPE, clazz);
            clazz = PropertyUtils.getPropertyType(bean, "doubleProperty");
            assertEquals("doubleProperty type", Double.TYPE, clazz);
            clazz = PropertyUtils.getPropertyType(bean, "dupProperty");
            assertEquals("dupProperty type", String.class, clazz);
            clazz = PropertyUtils.getPropertyType(bean, "floatProperty");
            assertEquals("floatProperty type", Float.TYPE, clazz);
            clazz = PropertyUtils.getPropertyType(bean, "intArray");
            assertEquals("intArray type", intArray.getClass(), clazz);
            clazz = PropertyUtils.getPropertyType(bean, "intIndexed");
            assertEquals("intIndexed type", Integer.TYPE, clazz);
            clazz = PropertyUtils.getPropertyType(bean, "intProperty");
            assertEquals("intProperty type", Integer.TYPE, clazz);
            clazz = PropertyUtils.getPropertyType(bean, "listIndexed");
            assertEquals("listIndexed type", List.class, clazz);
            clazz = PropertyUtils.getPropertyType(bean, "longProperty");
            assertEquals("longProperty type", Long.TYPE, clazz);
            clazz = PropertyUtils.getPropertyType(bean, "mappedProperty");
            assertEquals("mappedProperty type", String.class, clazz);
            clazz = PropertyUtils.getPropertyType(bean, "mappedIntProperty");
            assertEquals("mappedIntProperty type", Integer.TYPE, clazz);
            clazz = PropertyUtils.getPropertyType(bean, "readOnlyProperty");
            assertEquals("readOnlyProperty type", String.class, clazz);
            clazz = PropertyUtils.getPropertyType(bean, "shortProperty");
            assertEquals("shortProperty type", Short.TYPE, clazz);
            clazz = PropertyUtils.getPropertyType(bean, "stringArray");
            assertEquals("stringArray type", stringArray.getClass(), clazz);
            clazz = PropertyUtils.getPropertyType(bean, "stringIndexed");
            assertEquals("stringIndexed type", String.class, clazz);
            clazz = PropertyUtils.getPropertyType(bean, "stringProperty");
            assertEquals("stringProperty type", String.class, clazz);
            clazz = PropertyUtils.getPropertyType(bean, "writeOnlyProperty");
            assertEquals("writeOnlyProperty type", String.class, clazz);

            // Nested Properties
            clazz = PropertyUtils.getPropertyType(bean, "nested.booleanProperty");
            assertEquals("booleanProperty type", Boolean.TYPE, clazz);
            clazz = PropertyUtils.getPropertyType(bean, "nested.booleanSecond");
            assertEquals("booleanSecond type", Boolean.TYPE, clazz);
            clazz = PropertyUtils.getPropertyType(bean, "nested.doubleProperty");
            assertEquals("doubleProperty type", Double.TYPE, clazz);
            clazz = PropertyUtils.getPropertyType(bean, "nested.dupProperty");
            assertEquals("dupProperty type", String.class, clazz);
            clazz = PropertyUtils.getPropertyType(bean, "nested.floatProperty");
            assertEquals("floatProperty type", Float.TYPE, clazz);
            clazz = PropertyUtils.getPropertyType(bean, "nested.intArray");
            assertEquals("intArray type", intArray.getClass(), clazz);
            clazz = PropertyUtils.getPropertyType(bean, "nested.intIndexed");
            assertEquals("intIndexed type", Integer.TYPE, clazz);
            clazz = PropertyUtils.getPropertyType(bean, "nested.intProperty");
            assertEquals("intProperty type", Integer.TYPE, clazz);
            clazz = PropertyUtils.getPropertyType(bean, "nested.listIndexed");
            assertEquals("listIndexed type", List.class, clazz);
            clazz = PropertyUtils.getPropertyType(bean, "nested.longProperty");
            assertEquals("longProperty type", Long.TYPE, clazz);
            clazz = PropertyUtils.getPropertyType(bean, "nested.mappedProperty");
            assertEquals("mappedProperty type", String.class, clazz);
            clazz = PropertyUtils.getPropertyType(bean, "nested.mappedIntProperty");
            assertEquals("mappedIntProperty type", Integer.TYPE, clazz);
            clazz = PropertyUtils.getPropertyType(bean, "nested.readOnlyProperty");
            assertEquals("readOnlyProperty type", String.class, clazz);
            clazz = PropertyUtils.getPropertyType(bean, "nested.shortProperty");
            assertEquals("shortProperty type", Short.TYPE, clazz);
            clazz = PropertyUtils.getPropertyType(bean, "nested.stringArray");
            assertEquals("stringArray type", stringArray.getClass(), clazz);
            clazz = PropertyUtils.getPropertyType(bean, "nested.stringIndexed");
            assertEquals("stringIndexed type", String.class, clazz);
            clazz = PropertyUtils.getPropertyType(bean, "nested.stringProperty");
            assertEquals("stringProperty type", String.class, clazz);
            clazz = PropertyUtils.getPropertyType(bean, "nested.writeOnlyProperty");
            assertEquals("writeOnlyProperty type", String.class, clazz);

            // Nested DynaBean
            clazz = PropertyUtils.getPropertyType(bean, "nestedDynaBean");
            assertEquals("nestedDynaBean type", DynaBean.class, clazz);
            clazz = PropertyUtils.getPropertyType(bean, "nestedDynaBean.stringProperty");
            assertEquals("nestedDynaBean.stringProperty type", String.class, clazz);
            clazz = PropertyUtils.getPropertyType(bean, "nestedDynaBean.nestedBean");
            assertEquals("nestedDynaBean.nestedBean type", TestBean.class, clazz);
            clazz = PropertyUtils.getPropertyType(bean, "nestedDynaBean.nestedBean.nestedDynaBean");
            assertEquals("nestedDynaBean.nestedBean.nestedDynaBean type", DynaBean.class, clazz);
            clazz = PropertyUtils.getPropertyType(bean, "nestedDynaBean.nestedBean.nestedDynaBean.stringProperty");
            assertEquals("nestedDynaBean.nestedBean.nestedDynaBean.stringPropert type", String.class, clazz);

            // test Null
            clazz = PropertyUtils.getPropertyType(bean, "nestedDynaBean.nullDynaBean");
            assertEquals("nestedDynaBean.nullDynaBean type", DynaBean.class, clazz);
            try {
                clazz = PropertyUtils.getPropertyType(bean, "nestedDynaBean.nullDynaBean.foo");
                fail("Expected NestedNullException for nestedDynaBean.nullDynaBean.foo");
            } catch (final NestedNullException e) {
                // expected
            }

        } catch (final Exception e) {
            fail("Exception: " + e.getMessage());
        }

    }

    /**
     * Test accessing a public sub-bean of a package scope bean
     */
    public void testGetPublicSubBean_of_PackageBean() {

        final PublicSubBean bean = new PublicSubBean();
        bean.setFoo("foo-start");
        bean.setBar("bar-start");
        Object result = null;

        // Get Foo
        try {
            result = PropertyUtils.getProperty(bean, "foo");
        } catch (final Throwable t) {
            fail("getProperty(foo) threw " + t);
        }
        assertEquals("foo property", "foo-start", result);

        // Get Bar
        try {
            result = PropertyUtils.getProperty(bean, "bar");
        } catch (final Throwable t) {
            fail("getProperty(bar) threw " + t);
        }
        assertEquals("bar property", "bar-start", result);
    }

    /**
     * Base for testGetReadMethod() series of tests.
     *
     * @param bean       Bean for which to retrieve read methods.
     * @param properties Property names to search for
     * @param className  Class name where this method should be defined
     */
    protected void testGetReadMethod(final Object bean, final String[] properties, final String className) {

        final PropertyDescriptor[] pd = PropertyUtils.getPropertyDescriptors(bean);
        for (final String propertie : properties) {

            // Identify the property descriptor for this property
            if (propertie.equals("intIndexed")) {
                continue;
            }
            if (propertie.equals("stringIndexed")) {
                continue;
            }
            if (propertie.equals("writeOnlyProperty")) {
                continue;
            }
            int n = -1;
            for (int j = 0; j < pd.length; j++) {
                if (propertie.equals(pd[j].getName())) {
                    n = j;
                    break;
                }
            }
            assertTrue("PropertyDescriptor for " + propertie, n >= 0);

            // Locate an accessible property reader method for it
            final Method reader = PropertyUtils.getReadMethod(pd[n]);
            assertNotNull("Reader for " + propertie, reader);
            final Class<?> clazz = reader.getDeclaringClass();
            assertNotNull("Declaring class for " + propertie, clazz);
            assertEquals("Correct declaring class for " + propertie, clazz.getName(), className);

            // Actually call the reader method we received
            try {
                reader.invoke(bean, (Object[]) new Class<?>[0]);
            } catch (final Throwable t) {
                fail("Call for " + propertie + ": " + t);
            }

        }

    }

    /**
     * Test getting accessible property reader methods for a specified list of properties of our standard test bean.
     */
    public void testGetReadMethodBasic() {

        testGetReadMethod(bean, properties, TEST_BEAN_CLASS);

    }

    /**
     * Test getting accessible property reader methods for a specified list of properties of a package private subclass of our standard test bean.
     */
    public void testGetReadMethodPackageSubclass() {

        testGetReadMethod(beanPackageSubclass, properties, TEST_BEAN_CLASS);

    }

    /**
     * Test getting accessible property reader methods for a specified list of properties that are declared either directly or via implemented interfaces.
     */
    public void testGetReadMethodPublicInterface() {

        // Properties "bar" and "baz" are visible via implemented interfaces
        // (one direct and one indirect)
        testGetReadMethod(beanPrivate, new String[] { "bar" }, PRIVATE_DIRECT_CLASS);
        testGetReadMethod(beanPrivate, new String[] { "baz" }, PRIVATE_INDIRECT_CLASS);

        // Properties "bar" and "baz" are visible via implemented interfaces
        // (one direct and one indirect). The interface is implemented in
        // a superclass
        testGetReadMethod(beanPrivateSubclass, new String[] { "bar" }, PRIVATE_DIRECT_CLASS);
        testGetReadMethod(beanPrivateSubclass, new String[] { "baz" }, PRIVATE_INDIRECT_CLASS);

        // Property "foo" is not accessible because the underlying
        // class has package scope
        final PropertyDescriptor[] pd = PropertyUtils.getPropertyDescriptors(beanPrivate);
        int n = -1;
        for (int i = 0; i < pd.length; i++) {
            if ("foo".equals(pd[i].getName())) {
                n = i;
                break;
            }
        }
        assertTrue("Found foo descriptor", n >= 0);
        final Method reader = pd[n].getReadMethod();
        assertNotNull("Found foo read method", reader);
        try {
            reader.invoke(beanPrivate, (Object[]) new Class<?>[0]);
            fail("Foo reader did throw IllegalAccessException");
        } catch (final IllegalAccessException e) {
            // Expected result for this test
        } catch (final Throwable t) {
            fail("Invoke foo reader: " + t);
        }

    }

    /**
     * Test getting accessible property reader methods for a specified list of properties of a public subclass of our standard test bean.
     */
    public void testGetReadMethodPublicSubclass() {

        testGetReadMethod(beanPublicSubclass, properties, TEST_BEAN_CLASS);

    }

    /** Text case for setting properties on inner classes */
    public void testGetSetInnerBean() throws Exception {
        final BeanWithInnerBean bean = new BeanWithInnerBean();

        PropertyUtils.setProperty(bean, "innerBean.fish(loiterTimer)", "5");
        String out = (String) PropertyUtils.getProperty(bean.getInnerBean(), "fish(loiterTimer)");
        assertEquals("(1) Inner class property set/get property failed.", "5", out);

        out = (String) PropertyUtils.getProperty(bean, "innerBean.fish(loiterTimer)");

        assertEquals("(2) Inner class property set/get property failed.", "5", out);
    }

    /** Text case for setting properties on parent */
    public void testGetSetParentBean() throws Exception {

        final SonOfAlphaBean bean = new SonOfAlphaBean("Roger");

        final String out = (String) PropertyUtils.getProperty(bean, "name");
        assertEquals("(1) Get/Set On Parent.", "Roger", out);

        PropertyUtils.setProperty(bean, "name", "abcd");
        assertEquals("(2) Get/Set On Parent.", "abcd", bean.getName());
    }

    /**
     * Corner cases on getSimpleProperty invalid arguments.
     */
    public void testGetSimpleArguments() {

        try {
            PropertyUtils.getSimpleProperty(null, "stringProperty");
            fail("Should throw IllegalArgumentException 1");
        } catch (final IllegalArgumentException e) {
            // Expected response
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of IllegalArgumentException 1");
        }

        try {
            PropertyUtils.getSimpleProperty(bean, null);
            fail("Should throw IllegalArgumentException 2");
        } catch (final IllegalArgumentException e) {
            // Expected response
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of IllegalArgumentException 2");
        }

    }

    /**
     * Test getSimpleProperty on a boolean property.
     */
    public void testGetSimpleBoolean() {

        try {
            final Object value = PropertyUtils.getSimpleProperty(bean, "booleanProperty");
            assertNotNull("Got a value", value);
            assertTrue("Got correct type", value instanceof Boolean);
            assertTrue("Got correct value", ((Boolean) value).booleanValue() == bean.getBooleanProperty());
        } catch (final IllegalAccessException e) {
            fail("IllegalAccessException");
        } catch (final IllegalArgumentException e) {
            fail("IllegalArgumentException");
        } catch (final InvocationTargetException e) {
            fail("InvocationTargetException");
        } catch (final NoSuchMethodException e) {
            fail("NoSuchMethodException");
        }

    }

    /**
     * Test getSimpleProperty on a double property.
     */
    public void testGetSimpleDouble() {

        try {
            final Object value = PropertyUtils.getSimpleProperty(bean, "doubleProperty");
            assertNotNull("Got a value", value);
            assertTrue("Got correct type", value instanceof Double);
            assertEquals("Got correct value", ((Double) value).doubleValue(), bean.getDoubleProperty(), 0.005);
        } catch (final IllegalAccessException e) {
            fail("IllegalAccessException");
        } catch (final IllegalArgumentException e) {
            fail("IllegalArgumentException");
        } catch (final InvocationTargetException e) {
            fail("InvocationTargetException");
        } catch (final NoSuchMethodException e) {
            fail("NoSuchMethodException");
        }

    }

    /**
     * Test getSimpleProperty on a float property.
     */
    public void testGetSimpleFloat() {

        try {
            final Object value = PropertyUtils.getSimpleProperty(bean, "floatProperty");
            assertNotNull("Got a value", value);
            assertTrue("Got correct type", value instanceof Float);
            assertEquals("Got correct value", ((Float) value).floatValue(), bean.getFloatProperty(), (float) 0.005);
        } catch (final IllegalAccessException e) {
            fail("IllegalAccessException");
        } catch (final IllegalArgumentException e) {
            fail("IllegalArgumentException");
        } catch (final InvocationTargetException e) {
            fail("InvocationTargetException");
        } catch (final NoSuchMethodException e) {
            fail("NoSuchMethodException");
        }

    }

    /**
     * Negative test getSimpleProperty on an indexed property.
     */
    public void testGetSimpleIndexed() {

        try {
            PropertyUtils.getSimpleProperty(bean, "intIndexed[0]");
            fail("Should have thrown IllegalArgumentException");
        } catch (final IllegalAccessException e) {
            fail("IllegalAccessException");
        } catch (final IllegalArgumentException e) {
            // Correct result for this test
        } catch (final InvocationTargetException e) {
            fail("InvocationTargetException");
        } catch (final NoSuchMethodException e) {
            fail("NoSuchMethodException");
        }

    }

    /**
     * Test getSimpleProperty on an int property.
     */
    public void testGetSimpleInt() {

        try {
            final Object value = PropertyUtils.getSimpleProperty(bean, "intProperty");
            assertNotNull("Got a value", value);
            assertTrue("Got correct type", value instanceof Integer);
            assertEquals("Got correct value", ((Integer) value).intValue(), bean.getIntProperty());
        } catch (final IllegalAccessException e) {
            fail("IllegalAccessException");
        } catch (final IllegalArgumentException e) {
            fail("IllegalArgumentException");
        } catch (final InvocationTargetException e) {
            fail("InvocationTargetException");
        } catch (final NoSuchMethodException e) {
            fail("NoSuchMethodException");
        }

    }

    /**
     * Test getSimpleProperty on a long property.
     */
    public void testGetSimpleLong() {

        try {
            final Object value = PropertyUtils.getSimpleProperty(bean, "longProperty");
            assertNotNull("Got a value", value);
            assertTrue("Got correct type", value instanceof Long);
            assertEquals("Got correct value", ((Long) value).longValue(), bean.getLongProperty());
        } catch (final IllegalAccessException e) {
            fail("IllegalAccessException");
        } catch (final IllegalArgumentException e) {
            fail("IllegalArgumentException");
        } catch (final InvocationTargetException e) {
            fail("InvocationTargetException");
        } catch (final NoSuchMethodException e) {
            fail("NoSuchMethodException");
        }

    }

    /**
     * Negative test getSimpleProperty on a nested property.
     */
    public void testGetSimpleNested() {

        try {
            PropertyUtils.getSimpleProperty(bean, "nested.stringProperty");
            fail("Should have thrown IllegalArgumentException");
        } catch (final IllegalAccessException e) {
            fail("IllegalAccessException");
        } catch (final IllegalArgumentException e) {
            // Correct result for this test
        } catch (final InvocationTargetException e) {
            fail("InvocationTargetException");
        } catch (final NoSuchMethodException e) {
            fail("NoSuchMethodException");
        }

    }

    /**
     * Test getSimpleProperty on a read-only String property.
     */
    public void testGetSimpleReadOnly() {

        try {
            final Object value = PropertyUtils.getSimpleProperty(bean, "readOnlyProperty");
            assertNotNull("Got a value", value);
            assertTrue("Got correct type", value instanceof String);
            assertEquals("Got correct value", (String) value, bean.getReadOnlyProperty());
        } catch (final IllegalAccessException e) {
            fail("IllegalAccessException");
        } catch (final IllegalArgumentException e) {
            fail("IllegalArgumentException");
        } catch (final InvocationTargetException e) {
            fail("InvocationTargetException");
        } catch (final NoSuchMethodException e) {
            fail("NoSuchMethodException");
        }

    }

    /**
     * Test getSimpleProperty on a short property.
     */
    public void testGetSimpleShort() {

        try {
            final Object value = PropertyUtils.getSimpleProperty(bean, "shortProperty");
            assertNotNull("Got a value", value);
            assertTrue("Got correct type", value instanceof Short);
            assertEquals("Got correct value", ((Short) value).shortValue(), bean.getShortProperty());
        } catch (final IllegalAccessException e) {
            fail("IllegalAccessException");
        } catch (final IllegalArgumentException e) {
            fail("IllegalArgumentException");
        } catch (final InvocationTargetException e) {
            fail("InvocationTargetException");
        } catch (final NoSuchMethodException e) {
            fail("NoSuchMethodException");
        }

    }

    /**
     * Test getSimpleProperty on a String property.
     */
    public void testGetSimpleString() {

        try {
            final Object value = PropertyUtils.getSimpleProperty(bean, "stringProperty");
            assertNotNull("Got a value", value);
            assertTrue("Got correct type", value instanceof String);
            assertEquals("Got correct value", (String) value, bean.getStringProperty());
        } catch (final IllegalAccessException e) {
            fail("IllegalAccessException");
        } catch (final IllegalArgumentException e) {
            fail("IllegalArgumentException");
        } catch (final InvocationTargetException e) {
            fail("InvocationTargetException");
        } catch (final NoSuchMethodException e) {
            fail("NoSuchMethodException");
        }

    }

    /**
     * Negative test getSimpleProperty on an unknown property.
     */
    public void testGetSimpleUnknown() {

        try {
            PropertyUtils.getSimpleProperty(bean, "unknown");
            fail("Should have thrown NoSuchMethodException");
        } catch (final IllegalAccessException e) {
            fail("IllegalAccessException");
        } catch (final IllegalArgumentException e) {
            fail("IllegalArgumentException");
        } catch (final InvocationTargetException e) {
            fail("InvocationTargetException");
        } catch (final NoSuchMethodException e) {
            // Correct result for this test
            assertEquals("Unknown property 'unknown' on class '" + bean.getClass() + "'", e.getMessage());
        }

    }

    /**
     * Test getSimpleProperty on a write-only String property.
     */
    public void testGetSimpleWriteOnly() {

        try {
            PropertyUtils.getSimpleProperty(bean, "writeOnlyProperty");
            fail("Should have thrown NoSuchMethodException");
        } catch (final IllegalAccessException e) {
            fail("IllegalAccessException");
        } catch (final IllegalArgumentException e) {
            fail("IllegalArgumentException");
        } catch (final InvocationTargetException e) {
            fail("InvocationTargetException");
        } catch (final NoSuchMethodException e) {
            // Correct result for this test
            assertEquals("Property 'writeOnlyProperty' has no getter method in class '" + bean.getClass() + "'", e.getMessage());
        }

    }

    /**
     * Base for testGetWriteMethod() series of tests.
     *
     * @param bean       Bean for which to retrieve write methods.
     * @param properties Property names to search for
     * @param className  Class name where this method should be defined
     */
    protected void testGetWriteMethod(final Object bean, final String[] properties, final String className) {

        final PropertyDescriptor[] pd = PropertyUtils.getPropertyDescriptors(bean);
        for (final String property : properties) {

            // Identify the property descriptor for this property
            if (property.equals("intIndexed")) {
                continue;
            }
            if (property.equals("listIndexed")) {
                continue;
            }
            if (property.equals("nested")) {
                continue; // This property is read only
            }
            if (property.equals("readOnlyProperty")) {
                continue;
            }
            if (property.equals("stringIndexed")) {
                continue;
            }
            int n = -1;
            for (int j = 0; j < pd.length; j++) {
                if (property.equals(pd[j].getName())) {
                    n = j;
                    break;
                }
            }
            assertTrue("PropertyDescriptor for " + property, n >= 0);

            // Locate an accessible property reader method for it
            final Method writer = PropertyUtils.getWriteMethod(pd[n]);
            assertNotNull("Writer for " + property, writer);
            final Class<?> clazz = writer.getDeclaringClass();
            assertNotNull("Declaring class for " + property, clazz);
            assertEquals("Correct declaring class for " + property, clazz.getName(), className);

        }

    }

    /**
     * Test getting accessible property writer methods for a specified list of properties of our standard test bean.
     */
    public void testGetWriteMethodBasic() {

        testGetWriteMethod(bean, properties, TEST_BEAN_CLASS);

    }

    /**
     * Test getting accessible property writer methods for a specified list of properties of a package private subclass of our standard test bean.
     */
    public void testGetWriteMethodPackageSubclass() {

        testGetWriteMethod(beanPackageSubclass, properties, TEST_BEAN_CLASS);

    }

    /**
     * Test getting accessible property writer methods for a specified list of properties of a public subclass of our standard test bean.
     */
    public void testGetWriteMethodPublicSubclass() {

        testGetWriteMethod(beanPublicSubclass, properties, TEST_BEAN_CLASS);

    }

    /**
     * Test isReadable() method.
     */
    public void testIsReadable() {
        String property = null;
        try {
            property = "stringProperty";
            assertTrue("Property " + property + " isReadable expected TRUE", PropertyUtils.isReadable(bean, property));
        } catch (final Throwable t) {
            fail("Property " + property + " isReadable Threw exception: " + t);
        }
        try {
            property = "stringIndexed";
            assertTrue("Property " + property + " isReadable expected TRUE", PropertyUtils.isReadable(bean, property));
        } catch (final Throwable t) {
            fail("Property " + property + " isReadable Threw exception: " + t);
        }
        try {
            property = "mappedProperty";
            assertTrue("Property " + property + " isReadable expected TRUE", PropertyUtils.isReadable(bean, property));
        } catch (final Throwable t) {
            fail("Property " + property + " isReadable Threw exception: " + t);
        }

        try {
            property = "nestedDynaBean";
            assertTrue("Property " + property + " isReadable expected TRUE", PropertyUtils.isReadable(bean, property));
        } catch (final Throwable t) {
            fail("Property " + property + " isReadable Threw exception: " + t);
        }

        try {
            property = "nestedDynaBean.stringProperty";
            assertTrue("Property " + property + " isReadable expected TRUE", PropertyUtils.isReadable(bean, property));
        } catch (final Throwable t) {
            fail("Property " + property + " isReadable Threw exception: " + t);
        }

        try {
            property = "nestedDynaBean.nestedBean";
            assertTrue("Property " + property + " isReadable expected TRUE", PropertyUtils.isReadable(bean, property));
        } catch (final Throwable t) {
            fail("Property " + property + " isReadable Threw exception: " + t);
        }

        try {
            property = "nestedDynaBean.nestedBean.nestedDynaBean";
            assertTrue("Property " + property + " isReadable expected TRUE", PropertyUtils.isReadable(bean, property));
        } catch (final Throwable t) {
            fail("Property " + property + " isReadable Threw exception: " + t);
        }

        try {
            property = "nestedDynaBean.nestedBean.nestedDynaBean.stringProperty";
            assertTrue("Property " + property + " isReadable expected TRUE", PropertyUtils.isReadable(bean, property));
        } catch (final Throwable t) {
            fail("Property " + property + " isReadable Threw exception: " + t);
        }

        try {
            property = "nestedDynaBean.nullDynaBean";
            assertTrue("Property " + property + " isReadable expected TRUE", PropertyUtils.isReadable(bean, property));
        } catch (final Throwable t) {
            fail("Property " + property + " isReadable Threw exception: " + t);
        }

        try {
            property = "nestedDynaBean.nullDynaBean.foo";
            assertTrue("Property " + property + " isReadable expected TRUE", PropertyUtils.isReadable(bean, property));
            fail("Property " + property + " isReadable expected NestedNullException");
        } catch (final NestedNullException e) {
            // expected result
        } catch (final Throwable t) {
            fail("Property " + property + " isReadable Threw exception: " + t);
        }
    }

    /**
     * Test isWriteable() method.
     */
    public void testIsWriteable() {
        String property = null;
        try {
            property = "stringProperty";
            assertTrue("Property " + property + " isWriteable expected TRUE", PropertyUtils.isWriteable(bean, property));
        } catch (final Throwable t) {
            fail("Property " + property + " isWriteable Threw exception: " + t);
        }
        try {
            property = "stringIndexed";
            assertTrue("Property " + property + " isWriteable expected TRUE", PropertyUtils.isWriteable(bean, property));
        } catch (final Throwable t) {
            fail("Property " + property + " isWriteable Threw exception: " + t);
        }
        try {
            property = "mappedProperty";
            assertTrue("Property " + property + " isWriteable expected TRUE", PropertyUtils.isWriteable(bean, property));
        } catch (final Throwable t) {
            fail("Property " + property + " isWriteable Threw exception: " + t);
        }

        try {
            property = "nestedDynaBean";
            assertTrue("Property " + property + " isWriteable expected TRUE", PropertyUtils.isWriteable(bean, property));
        } catch (final Throwable t) {
            fail("Property " + property + " isWriteable Threw exception: " + t);
        }

        try {
            property = "nestedDynaBean.stringProperty";
            assertTrue("Property " + property + " isWriteable expected TRUE", PropertyUtils.isWriteable(bean, property));
        } catch (final Throwable t) {
            t.printStackTrace();
            fail("Property " + property + " isWriteable Threw exception: " + t);
        }

        try {
            property = "nestedDynaBean.nestedBean";
            assertTrue("Property " + property + " isWriteable expected TRUE", PropertyUtils.isWriteable(bean, property));
        } catch (final Throwable t) {
            fail("Property " + property + " isWriteable Threw exception: " + t);
        }

        try {
            property = "nestedDynaBean.nestedBean.nestedDynaBean";
            assertTrue("Property " + property + " isWriteable expected TRUE", PropertyUtils.isWriteable(bean, property));
        } catch (final Throwable t) {
            fail("Property " + property + " isWriteable Threw exception: " + t);
        }

        try {
            property = "nestedDynaBean.nestedBean.nestedDynaBean.stringProperty";
            assertTrue("Property " + property + " isWriteable expected TRUE", PropertyUtils.isWriteable(bean, property));
        } catch (final Throwable t) {
            fail("Property " + property + " isWriteable Threw exception: " + t);
        }

        try {
            property = "nestedDynaBean.nullDynaBean";
            assertTrue("Property " + property + " isWriteable expected TRUE", PropertyUtils.isWriteable(bean, property));
        } catch (final Throwable t) {
            fail("Property " + property + " isWriteable Threw exception: " + t);
        }

        try {
            property = "nestedDynaBean.nullDynaBean.foo";
            assertTrue("Property " + property + " isWriteable expected TRUE", PropertyUtils.isWriteable(bean, property));
            fail("Property " + property + " isWriteable expected NestedNullException");
        } catch (final NestedNullException e) {
            // expected result
        } catch (final Throwable t) {
            fail("Property " + property + " isWriteable Threw exception: " + t);
        }
    }

    /**
     * This tests to see that it is possible to subclass PropertyUtilsBean and change the behavior of setNestedProperty/getNestedProperty when dealing with
     * objects that implement Map.
     */
    public void testMapExtensionCustom() throws Exception {
        final PropsFirstPropertyUtilsBean utilsBean = new PropsFirstPropertyUtilsBean();
        final ExtendMapBean bean = new ExtendMapBean();

        // hardly worth testing this, really :-)
        bean.setUnusuallyNamedProperty("bean value");
        assertEquals("Set property direct failed", "bean value", bean.getUnusuallyNamedProperty());

        // setSimpleProperty should affect the simple property
        utilsBean.setSimpleProperty(bean, "unusuallyNamedProperty", "new value");
        assertEquals("Set property on map failed (1)", "new value", bean.getUnusuallyNamedProperty());

        // setNestedProperty with setter should affect the simple property
        // getNestedProperty with getter should obtain the simple property
        utilsBean.setProperty(bean, "unusuallyNamedProperty", "next value");
        assertEquals("Set property on map failed (2)", "next value", bean.getUnusuallyNamedProperty());
        assertEquals("setNestedProperty on non-simple property failed", "next value", utilsBean.getNestedProperty(bean, "unusuallyNamedProperty"));

        // setting property without setter should update the map
        // getting property without setter should fetch from the map
        utilsBean.setProperty(bean, "mapProperty", "value1");
        assertEquals("setNestedProperty on non-simple property failed", "value1", utilsBean.getNestedProperty(bean, "mapProperty"));

        final HashMap<String, Object> myMap = new HashMap<>();
        myMap.put("thebean", bean);
        utilsBean.getNestedProperty(myMap, "thebean.mapitem");
        utilsBean.getNestedProperty(myMap, "thebean(mapitem)");
    }

    /**
     * This tests to see that classes that implement Map always have their custom properties ignored.
     * <p>
     * Note that this behavior has changed several times over past releases of beanutils, breaking backwards compatibility each time. Here's hoping that the
     * current 1.7.1 release is the last time this behavior changes!
     */
    public void testMapExtensionDefault() throws Exception {
        final ExtendMapBean bean = new ExtendMapBean();

        // setting property direct should work, and not affect map
        bean.setUnusuallyNamedProperty("bean value");
        assertEquals("Set property direct failed", "bean value", bean.getUnusuallyNamedProperty());
        assertNull("Get on unset map property failed", PropertyUtils.getNestedProperty(bean, "unusuallyNamedProperty"));

        // setting simple property should call the setter method only, and not
        // affect the map.
        PropertyUtils.setSimpleProperty(bean, "unusuallyNamedProperty", "new value");
        assertEquals("Set property on map failed (1)", "new value", bean.getUnusuallyNamedProperty());
        assertNull("Get on unset map property failed", PropertyUtils.getNestedProperty(bean, "unusuallyNamedProperty"));

        // setting via setNestedProperty should affect the map only, and not
        // call the setter method.
        PropertyUtils.setProperty(bean, "unusuallyNamedProperty", "next value");
        assertEquals("setNestedProperty on map not visible to getNestedProperty", "next value",
                PropertyUtils.getNestedProperty(bean, "unusuallyNamedProperty"));
        assertEquals("Set nested property on map unexpected affected simple property", "new value", bean.getUnusuallyNamedProperty());
    }

    /**
     * Test the mappedPropertyType of MappedPropertyDescriptor.
     */
    public void testMappedPropertyType() throws Exception {

        MappedPropertyDescriptor desc;

        // Check a String property
        desc = (MappedPropertyDescriptor) PropertyUtils.getPropertyDescriptor(bean, "mappedProperty");
        assertEquals(String.class, desc.getMappedPropertyType());

        // Check an int property
        desc = (MappedPropertyDescriptor) PropertyUtils.getPropertyDescriptor(bean, "mappedIntProperty");
        assertEquals(Integer.TYPE, desc.getMappedPropertyType());

    }

    /**
     * There is an issue in setNestedProperty/getNestedProperty when the target bean is a map and the name string requests mapped or indexed operations on a
     * field. These are not supported for fields of a Map, but it's an easy mistake to make and this test case ensures that an appropriate exception is thrown
     * when a user does this.
     * <p>
     * The problem is with passing strings of form "a(b)" or "a[3]" to setNestedProperty or getNestedProperty when the target bean they are applied to
     * implements Map. These strings are actually requesting "the result of calling mapped method a on the target object with a parameter of b" or "the result
     * of calling indexed method a on the target object with a parameter of 3". And these requests are not valid when the target is a Map as a Map only supports
     * calling get(fieldName) or put(fieldName), neither of which can be further indexed with a string or an integer.
     * <p>
     * However it is likely that some users will assume that "a[3]" when applied to a map will be equivalent to (map.get("a"))[3] with the appropriate
     * typecasting, or for "a(b)" to be equivalent to map.get("a").get("b").
     * <p>
     * Here we verify that an exception is thrown if the user makes this mistake.
     */
    public void testNestedPropertyKeyOrIndexOnBeanImplementingMap() throws Exception {
        final HashMap<String, Object> map = new HashMap<>();
        final HashMap<String, Object> submap = new HashMap<>();
        final BetaBean betaBean1 = new BetaBean("test1");
        final BetaBean betaBean2 = new BetaBean("test2");

        // map.put("submap", submap)
        PropertyUtils.setNestedProperty(map, "submap", submap);

        // map.get("submap").put("beta1", betaBean1)
        PropertyUtils.setNestedProperty(map, "submap.beta1", betaBean1);
        assertEquals("Unexpected keys in map", "submap", keysToString(map));
        assertEquals("Unexpected keys in submap", "beta1", keysToString(submap));

        try {
            // One would expect that the command below would be equivalent to
            // Map m = (Map) map.get("submap");
            // m.put("beta2", betaBean2)
            // However this isn't how javabeans property methods work. A map
            // only effectively has "simple" properties, even when the
            // returned object is a Map or Array.
            PropertyUtils.setNestedProperty(map, "submap(beta2)", betaBean2);

            // What, no exception? In that case, setNestedProperties has
            // probably just tried to do
            // map.set("submap(beta2)", betaBean2)
            // which is almost certainly not what the used expected. This is
            // what beanutils 1.5.0 to 1.7.1 did....
            fail("Exception not thrown for invalid setNestedProperty syntax");
        } catch (final IllegalArgumentException ex) {
            // ok, getting an exception was expected. As it is of a generic
            // type, let's check the message string to make sure it really
            // was caused by the issue we expected.
            final int index = ex.getMessage().indexOf("Indexed or mapped properties are not supported");
            assertTrue("Unexpected exception message", index >= 0);
        }

        try {
            // One would expect that "submap[3]" would be equivalent to
            // Object[] objects = (Object[]) map.get("submap");
            // return objects[3];
            // However this isn't how javabeans property methods work. A map
            // only effectively has "simple" properties, even when the
            // returned object is a Map or Array.
            PropertyUtils.getNestedProperty(map, "submap[3]");

            // What, no exception? In that case, getNestedProperties has
            // probably just tried to do
            // map.get("submap[3]")
            // which is almost certainly not what the used expected. This is
            // what beanutils 1.5.0 to 1.7.1 did....
            fail("Exception not thrown for invalid setNestedProperty syntax");
        } catch (final IllegalArgumentException ex) {
            // ok, getting an exception was expected. As it is of a generic
            // type, let's check the message string to make sure it really
            // was caused by the issue we expected.
            final int index = ex.getMessage().indexOf("Indexed or mapped properties are not supported");
            assertTrue("Unexpected exception message", index >= 0);
        }
    }

    public void testNestedWithIndex() throws Exception {
        final NestedTestBean nestedBean = new NestedTestBean("base");
        nestedBean.init();
        nestedBean.getSimpleBeanProperty().init();

        NestedTestBean

        // test first calling properties on indexed beans

        value = (NestedTestBean) PropertyUtils.getProperty(nestedBean, "indexedProperty[0]");
        assertEquals("Cannot get simple index(1)", "Bean@0", value.getName());
        assertEquals("Bug in NestedTestBean", "NOT SET", value.getTestString());

        value = (NestedTestBean) PropertyUtils.getProperty(nestedBean, "indexedProperty[1]");
        assertEquals("Cannot get simple index(1)", "Bean@1", value.getName());
        assertEquals("Bug in NestedTestBean", "NOT SET", value.getTestString());

        String prop = (String) PropertyUtils.getProperty(nestedBean, "indexedProperty[0].testString");
        assertEquals("Get property on indexes failed (1)", "NOT SET", prop);

        prop = (String) PropertyUtils.getProperty(nestedBean, "indexedProperty[1].testString");
        assertEquals("Get property on indexes failed (2)", "NOT SET", prop);

        PropertyUtils.setProperty(nestedBean, "indexedProperty[0].testString", "Test#1");
        assertEquals("Cannot set property on indexed bean (1)", "Test#1", nestedBean.getIndexedProperty(0).getTestString());

        PropertyUtils.setProperty(nestedBean, "indexedProperty[1].testString", "Test#2");
        assertEquals("Cannot set property on indexed bean (2)", "Test#2", nestedBean.getIndexedProperty(1).getTestString());

        // test first calling indexed properties on a simple property

        value = (NestedTestBean) PropertyUtils.getProperty(nestedBean, "simpleBeanProperty");
        assertEquals("Cannot get simple bean", "Simple Property Bean", value.getName());
        assertEquals("Bug in NestedTestBean", "NOT SET", value.getTestString());

        value = (NestedTestBean) PropertyUtils.getProperty(nestedBean, "simpleBeanProperty.indexedProperty[3]");
        assertEquals("Cannot get index property on property", "Bean@3", value.getName());
        assertEquals("Bug in NestedTestBean", "NOT SET", value.getTestString());

        PropertyUtils.setProperty(nestedBean, "simpleBeanProperty.indexedProperty[3].testString", "Test#3");
        assertEquals("Cannot set property on indexed property on property", "Test#3", nestedBean.getSimpleBeanProperty().getIndexedProperty(3).getTestString());
    }

    /**
     * Tests whether a BeanIntrospector can be removed.
     */
    public void testRemoveBeanIntrospector() {
        assertTrue("Wrong result", PropertyUtils.removeBeanIntrospector(DefaultBeanIntrospector.INSTANCE));
        final PropertyDescriptor[] desc = PropertyUtils.getPropertyDescriptors(AlphaBean.class);
        assertEquals("Got descriptors", 0, desc.length);
        PropertyUtils.addBeanIntrospector(DefaultBeanIntrospector.INSTANCE);
    }

    /**
     * Tests whether a reset of the registered BeanIntrospectors can be performed.
     */
    public void testResetBeanIntrospectors() {
        assertTrue("Wrong result", PropertyUtils.removeBeanIntrospector(DefaultBeanIntrospector.INSTANCE));
        PropertyUtils.resetBeanIntrospectors();
        final PropertyDescriptor[] desc = PropertyUtils.getPropertyDescriptors(AlphaBean.class);
        assertTrue("Got no descriptors", desc.length > 0);
    }

    /**
     * Corner cases on setIndexedProperty invalid arguments.
     */
    public void testSetIndexedArguments() {

        // Use explicit index argument

        try {
            PropertyUtils.setIndexedProperty(null, "intArray", 0, Integer.valueOf(1));
            fail("Should throw IllegalArgumentException 1");
        } catch (final IllegalArgumentException e) {
            // Expected response
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of IllegalArgumentException 1");
        }

        try {
            PropertyUtils.setIndexedProperty(bean, null, 0, Integer.valueOf(1));
            fail("Should throw IllegalArgumentException 2");
        } catch (final IllegalArgumentException e) {
            // Expected response
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of IllegalArgumentException 2");
        }

        // Use index expression

        try {
            PropertyUtils.setIndexedProperty(null, "intArray[0]", Integer.valueOf(1));
            fail("Should throw IllegalArgumentException 3");
        } catch (final IllegalArgumentException e) {
            // Expected response
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of IllegalArgumentException 3");
        }

        try {
            PropertyUtils.setIndexedProperty(bean, "[0]", Integer.valueOf(1));
            fail("Should throw NoSuchMethodException 4");
        } catch (final NoSuchMethodException e) {
            // Expected response
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of NoSuchMethodException 4");
        }

        try {
            PropertyUtils.setIndexedProperty(bean, "intArray", Integer.valueOf(1));
            fail("Should throw IllegalArgumentException 5");
        } catch (final IllegalArgumentException e) {
            // Expected response
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of IllegalArgumentException 5");
        }

        // Use explicit index argument

        try {
            PropertyUtils.setIndexedProperty(null, "intIndexed", 0, Integer.valueOf(1));
            fail("Should throw IllegalArgumentException 1");
        } catch (final IllegalArgumentException e) {
            // Expected response
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of IllegalArgumentException 1");
        }

        try {
            PropertyUtils.setIndexedProperty(bean, null, 0, Integer.valueOf(1));
            fail("Should throw IllegalArgumentException 2");
        } catch (final IllegalArgumentException e) {
            // Expected response
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of IllegalArgumentException 2");
        }

        // Use index expression

        try {
            PropertyUtils.setIndexedProperty(null, "intIndexed[0]", Integer.valueOf(1));
            fail("Should throw IllegalArgumentException 3");
        } catch (final IllegalArgumentException e) {
            // Expected response
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of IllegalArgumentException 3");
        }

        try {
            PropertyUtils.setIndexedProperty(bean, "[0]", Integer.valueOf(1));
            fail("Should throw NoSuchMethodException 4");
        } catch (final NoSuchMethodException e) {
            // Expected response
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of NoSuchMethodException 4");
        }

        try {
            PropertyUtils.setIndexedProperty(bean, "intIndexed", Integer.valueOf(1));
            fail("Should throw IllegalArgumentException 5");
        } catch (final IllegalArgumentException e) {
            // Expected response
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of IllegalArgumentException 5");
        }

    }

    /**
     * Test setting an indexed value out of a multi-dimensional array
     */
    public void testSetIndexedArray() {
        final String[] firstArray = { "FIRST-1", "FIRST-2", "FIRST-3" };
        final String[] secondArray = { "SECOND-1", "SECOND-2", "SECOND-3", "SECOND-4" };
        final String[][] mainArray = { firstArray, secondArray };
        final TestBean bean = new TestBean(mainArray);
        assertEquals("BEFORE", "SECOND-3", bean.getString2dArray(1)[2]);
        try {
            PropertyUtils.setProperty(bean, "string2dArray[1][2]", "SECOND-3-UPDATED");
        } catch (final Throwable t) {
            fail("Threw " + t + "");
        }
        assertEquals("AFTER", "SECOND-3-UPDATED", bean.getString2dArray(1)[2]);
    }

    /**
     * Test setting an indexed value out of List of Lists
     */
    public void testSetIndexedList() {
        final String[] firstArray = { "FIRST-1", "FIRST-2", "FIRST-3" };
        final String[] secondArray = { "SECOND-1", "SECOND-2", "SECOND-3", "SECOND-4" };
        final List<Object> mainList = new ArrayList<>();
        mainList.add(Arrays.asList(firstArray));
        mainList.add(Arrays.asList(secondArray));
        final TestBean bean = new TestBean(mainList);
        assertEquals("BEFORE", "SECOND-4", ((List<?>) bean.getListIndexed().get(1)).get(3));
        try {
            PropertyUtils.setProperty(bean, "listIndexed[1][3]", "SECOND-4-UPDATED");
        } catch (final Throwable t) {
            fail("Threw " + t + "");
        }
        assertEquals("AFTER", "SECOND-4-UPDATED", ((List<?>) bean.getListIndexed().get(1)).get(3));
    }

    /**
     * Test setting a value out of a mapped Map
     */
    public void testSetIndexedMap() {
        final Map<String, Object> firstMap = new HashMap<>();
        firstMap.put("FIRST-KEY-1", "FIRST-VALUE-1");
        firstMap.put("FIRST-KEY-2", "FIRST-VALUE-2");
        final Map<String, Object> secondMap = new HashMap<>();
        secondMap.put("SECOND-KEY-1", "SECOND-VALUE-1");
        secondMap.put("SECOND-KEY-2", "SECOND-VALUE-2");

        final List<Object> mainList = new ArrayList<>();
        mainList.add(firstMap);
        mainList.add(secondMap);
        final TestBean bean = new TestBean(mainList);

        assertEquals("BEFORE", null, ((Map<?, ?>) bean.getListIndexed().get(0)).get("FIRST-NEW-KEY"));
        assertEquals("BEFORE", "SECOND-VALUE-1", ((Map<?, ?>) bean.getListIndexed().get(1)).get("SECOND-KEY-1"));
        try {
            PropertyUtils.setProperty(bean, "listIndexed[0](FIRST-NEW-KEY)", "FIRST-NEW-VALUE");
            PropertyUtils.setProperty(bean, "listIndexed[1](SECOND-KEY-1)", "SECOND-VALUE-1-UPDATED");
        } catch (final Throwable t) {
            fail("Threw " + t + "");
        }
        assertEquals("BEFORE", "FIRST-NEW-VALUE", ((Map<?, ?>) bean.getListIndexed().get(0)).get("FIRST-NEW-KEY"));
        assertEquals("AFTER", "SECOND-VALUE-1-UPDATED", ((Map<?, ?>) bean.getListIndexed().get(1)).get("SECOND-KEY-1"));
    }

    /**
     * Positive and negative tests on setIndexedProperty valid arguments.
     */
    public void testSetIndexedValues() {

        Object value = null;

        // Use explicit index argument

        try {
            PropertyUtils.setIndexedProperty(bean, "dupProperty", 0, "New 0");
            value = PropertyUtils.getIndexedProperty(bean, "dupProperty", 0);
            assertNotNull("Returned new value 0", value);
            assertTrue("Returned String new value 0", value instanceof String);
            assertEquals("Returned correct new value 0", "New 0", (String) value);
        } catch (final Throwable t) {
            fail("Threw " + t);
        }

        try {
            PropertyUtils.setIndexedProperty(bean, "intArray", 0, Integer.valueOf(1));
            value = PropertyUtils.getIndexedProperty(bean, "intArray", 0);
            assertNotNull("Returned new value 0", value);
            assertTrue("Returned Integer new value 0", value instanceof Integer);
            assertEquals("Returned correct new value 0", 1, ((Integer) value).intValue());
        } catch (final Throwable t) {
            fail("Threw " + t);
        }

        try {
            PropertyUtils.setIndexedProperty(bean, "intIndexed", 1, Integer.valueOf(11));
            value = PropertyUtils.getIndexedProperty(bean, "intIndexed", 1);
            assertNotNull("Returned new value 1", value);
            assertTrue("Returned Integer new value 1", value instanceof Integer);
            assertEquals("Returned correct new value 1", 11, ((Integer) value).intValue());
        } catch (final Throwable t) {
            fail("Threw " + t);
        }

        try {
            PropertyUtils.setIndexedProperty(bean, "listIndexed", 2, "New Value 2");
            value = PropertyUtils.getIndexedProperty(bean, "listIndexed", 2);
            assertNotNull("Returned new value 2", value);
            assertTrue("Returned String new value 2", value instanceof String);
            assertEquals("Returned correct new value 2", "New Value 2", (String) value);
        } catch (final Throwable t) {
            fail("Threw " + t);
        }

        try {
            PropertyUtils.setIndexedProperty(bean, "stringArray", 2, "New Value 2");
            value = PropertyUtils.getIndexedProperty(bean, "stringArray", 2);
            assertNotNull("Returned new value 2", value);
            assertTrue("Returned String new value 2", value instanceof String);
            assertEquals("Returned correct new value 2", "New Value 2", (String) value);
        } catch (final Throwable t) {
            fail("Threw " + t);
        }

        try {
            PropertyUtils.setIndexedProperty(bean, "stringArray", 3, "New Value 3");
            value = PropertyUtils.getIndexedProperty(bean, "stringArray", 3);
            assertNotNull("Returned new value 3", value);
            assertTrue("Returned String new value 3", value instanceof String);
            assertEquals("Returned correct new value 3", "New Value 3", (String) value);
        } catch (final Throwable t) {
            fail("Threw " + t);
        }

        // Use index expression

        try {
            PropertyUtils.setIndexedProperty(bean, "dupProperty[4]", "New 4");
            value = PropertyUtils.getIndexedProperty(bean, "dupProperty[4]");
            assertNotNull("Returned new value 4", value);
            assertTrue("Returned String new value 4", value instanceof String);
            assertEquals("Returned correct new value 4", "New 4", (String) value);
        } catch (final Throwable t) {
            fail("Threw " + t);
        }

        try {
            PropertyUtils.setIndexedProperty(bean, "intArray[4]", Integer.valueOf(1));
            value = PropertyUtils.getIndexedProperty(bean, "intArray[4]");
            assertNotNull("Returned new value 4", value);
            assertTrue("Returned Integer new value 4", value instanceof Integer);
            assertEquals("Returned correct new value 4", 1, ((Integer) value).intValue());
        } catch (final Throwable t) {
            fail("Threw " + t);
        }

        try {
            PropertyUtils.setIndexedProperty(bean, "intIndexed[3]", Integer.valueOf(11));
            value = PropertyUtils.getIndexedProperty(bean, "intIndexed[3]");
            assertNotNull("Returned new value 5", value);
            assertTrue("Returned Integer new value 5", value instanceof Integer);
            assertEquals("Returned correct new value 5", 11, ((Integer) value).intValue());
        } catch (final Throwable t) {
            fail("Threw " + t);
        }

        try {
            PropertyUtils.setIndexedProperty(bean, "listIndexed[1]", "New Value 2");
            value = PropertyUtils.getIndexedProperty(bean, "listIndexed[1]");
            assertNotNull("Returned new value 6", value);
            assertTrue("Returned String new value 6", value instanceof String);
            assertEquals("Returned correct new value 6", "New Value 2", (String) value);
        } catch (final Throwable t) {
            fail("Threw " + t);
        }

        try {
            PropertyUtils.setIndexedProperty(bean, "stringArray[1]", "New Value 2");
            value = PropertyUtils.getIndexedProperty(bean, "stringArray[2]");
            assertNotNull("Returned new value 6", value);
            assertTrue("Returned String new value 6", value instanceof String);
            assertEquals("Returned correct new value 6", "New Value 2", (String) value);
        } catch (final Throwable t) {
            fail("Threw " + t);
        }

        try {
            PropertyUtils.setIndexedProperty(bean, "stringArray[0]", "New Value 3");
            value = PropertyUtils.getIndexedProperty(bean, "stringArray[0]");
            assertNotNull("Returned new value 7", value);
            assertTrue("Returned String new value 7", value instanceof String);
            assertEquals("Returned correct new value 7", "New Value 3", (String) value);
        } catch (final Throwable t) {
            fail("Threw " + t);
        }

        // Index out of bounds tests

        try {
            PropertyUtils.setIndexedProperty(bean, "dupProperty", -1, "New -1");
            fail("Should have thrown ArrayIndexOutOfBoundsException");
        } catch (final ArrayIndexOutOfBoundsException t) {
            // Expected results
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException");
        }

        try {
            PropertyUtils.setIndexedProperty(bean, "dupProperty", 5, "New 5");
            fail("Should have thrown ArrayIndexOutOfBoundsException");
        } catch (final ArrayIndexOutOfBoundsException t) {
            // Expected results
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException");
        }

        try {
            PropertyUtils.setIndexedProperty(bean, "intArray", -1, Integer.valueOf(0));
            fail("Should have thrown ArrayIndexOutOfBoundsException");
        } catch (final ArrayIndexOutOfBoundsException t) {
            // Expected results
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException");
        }

        try {
            PropertyUtils.setIndexedProperty(bean, "intArray", 5, Integer.valueOf(0));
            fail("Should have thrown ArrayIndexOutOfBoundsException");
        } catch (final ArrayIndexOutOfBoundsException t) {
            // Expected results
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException");
        }

        try {
            PropertyUtils.setIndexedProperty(bean, "intIndexed", -1, Integer.valueOf(0));
            fail("Should have thrown ArrayIndexOutOfBoundsException");
        } catch (final ArrayIndexOutOfBoundsException t) {
            // Expected results
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException");
        }

        try {
            PropertyUtils.setIndexedProperty(bean, "intIndexed", 5, Integer.valueOf(0));
            fail("Should have thrown ArrayIndexOutOfBoundsException");
        } catch (final ArrayIndexOutOfBoundsException t) {
            // Expected results
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException");
        }

        try {
            PropertyUtils.setIndexedProperty(bean, "listIndexed", 5, "New String");
            fail("Should have thrown IndexOutOfBoundsException");
        } catch (final IndexOutOfBoundsException t) {
            // Expected results
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of IndexOutOfBoundsException");
        }

        try {
            PropertyUtils.setIndexedProperty(bean, "listIndexed", -1, "New String");
            fail("Should have thrown IndexOutOfBoundsException");
        } catch (final IndexOutOfBoundsException t) {
            // Expected results
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of IndexOutOfBoundsException");
        }

        try {
            PropertyUtils.setIndexedProperty(bean, "stringArray", -1, "New String");
            fail("Should have thrown ArrayIndexOutOfBoundsException");
        } catch (final ArrayIndexOutOfBoundsException t) {
            // Expected results
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException");
        }

        try {
            PropertyUtils.setIndexedProperty(bean, "stringArray", 5, "New String");
            fail("Should have thrown ArrayIndexOutOfBoundsException");
        } catch (final ArrayIndexOutOfBoundsException t) {
            // Expected results
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException");
        }

        try {
            PropertyUtils.setIndexedProperty(bean, "stringIndexed", -1, "New String");
            fail("Should have thrown ArrayIndexOutOfBoundsException");
        } catch (final ArrayIndexOutOfBoundsException t) {
            // Expected results
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException");
        }

        try {
            PropertyUtils.setIndexedProperty(bean, "stringIndexed", 5, "New String");
            fail("Should have thrown ArrayIndexOutOfBoundsException");
        } catch (final ArrayIndexOutOfBoundsException t) {
            // Expected results
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException");
        }

    }

    /**
     * Corner cases on getMappedProperty invalid arguments.
     */
    public void testSetMappedArguments() {

        // Use explicit key argument

        try {
            PropertyUtils.setMappedProperty(null, "mappedProperty", "First Key", "First Value");
            fail("Should throw IllegalArgumentException 1");
        } catch (final IllegalArgumentException e) {
            // Expected response
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of IllegalArgumentException 1");
        }

        try {
            PropertyUtils.setMappedProperty(bean, null, "First Key", "First Value");
            fail("Should throw IllegalArgumentException 2");
        } catch (final IllegalArgumentException e) {
            // Expected response
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of IllegalArgumentException 2");
        }

        try {
            PropertyUtils.setMappedProperty(bean, "mappedProperty", null, "First Value");
            fail("Should throw IllegalArgumentException 3");
        } catch (final IllegalArgumentException e) {
            // Expected response
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of IllegalArgumentException 3");
        }

        // Use key expression

        try {
            PropertyUtils.setMappedProperty(null, "mappedProperty(First Key)", "First Value");
            fail("Should throw IllegalArgumentException 4");
        } catch (final IllegalArgumentException e) {
            // Expected response
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of IllegalArgumentException 4");
        }

        try {
            PropertyUtils.setMappedProperty(bean, "(Second Key)", "Second Value");
            fail("Should throw IllegalArgumentException 5");
        } catch (final NoSuchMethodException e) {
            // Expected response
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of NoSuchMethodException 5");
        }

        try {
            PropertyUtils.setMappedProperty(bean, "mappedProperty", "Third Value");
            fail("Should throw IllegalArgumentException 6");
        } catch (final IllegalArgumentException e) {
            // Expected response
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of IllegalArgumentException 6");
        }

    }

    /**
     * Test setting an indexed value out of a mapped array
     */
    public void testSetMappedArray() {
        final TestBean bean = new TestBean();
        final String[] array = { "abc", "def", "ghi" };
        bean.getMapProperty().put("mappedArray", array);

        assertEquals("BEFORE", "def", ((String[]) bean.getMapProperty().get("mappedArray"))[1]);
        try {
            PropertyUtils.setProperty(bean, "mapProperty(mappedArray)[1]", "DEF-UPDATED");
        } catch (final Throwable t) {
            fail("Threw " + t + "");
        }
        assertEquals("AFTER", "DEF-UPDATED", ((String[]) bean.getMapProperty().get("mappedArray"))[1]);
    }

    /**
     * Test setting an indexed value out of a mapped List
     */
    public void testSetMappedList() {
        final TestBean bean = new TestBean();
        final List<Object> list = new ArrayList<>();
        list.add("klm");
        list.add("nop");
        list.add("qrs");
        bean.getMapProperty().put("mappedList", list);

        assertEquals("BEFORE", "klm", ((List<?>) bean.getMapProperty().get("mappedList")).get(0));
        try {
            PropertyUtils.setProperty(bean, "mapProperty(mappedList)[0]", "KLM-UPDATED");
        } catch (final Throwable t) {
            fail("Threw " + t + "");
        }
        assertEquals("AFTER", "KLM-UPDATED", ((List<?>) bean.getMapProperty().get("mappedList")).get(0));
    }

    /**
     * Test setting a value out of a mapped Map
     */
    public void testSetMappedMap() {
        final TestBean bean = new TestBean();
        final Map<String, Object> map = new HashMap<>();
        map.put("sub-key-1", "sub-value-1");
        map.put("sub-key-2", "sub-value-2");
        map.put("sub-key-3", "sub-value-3");
        bean.getMapProperty().put("mappedMap", map);

        assertEquals("BEFORE", "sub-value-3", ((Map<?, ?>) bean.getMapProperty().get("mappedMap")).get("sub-key-3"));
        try {
            PropertyUtils.setProperty(bean, "mapProperty(mappedMap)(sub-key-3)", "SUB-KEY-3-UPDATED");
        } catch (final Throwable t) {
            fail("Threw " + t + "");
        }
        assertEquals("AFTER", "SUB-KEY-3-UPDATED", ((Map<?, ?>) bean.getMapProperty().get("mappedMap")).get("sub-key-3"));
    }

    /**
     * Test setting mapped values with periods in the key.
     */
    public void testSetMappedPeriods() {

        // -------- PropertyUtils.setMappedProperty()--------
        bean.setMappedProperty("key.with.a.dot", "Special Value");
        assertEquals("Can retrieve directly (A)", "Special Value", bean.getMappedProperty("key.with.a.dot"));

        try {
            PropertyUtils.setMappedProperty(bean, "mappedProperty", "key.with.a.dot", "Updated Special Value");
            assertEquals("Check set via setMappedProperty", "Updated Special Value", bean.getMappedProperty("key.with.a.dot"));
        } catch (final Exception e) {
            fail("Thew exception: " + e);
        }

        // -------- PropertyUtils.setNestedProperty() --------
        bean.setMappedProperty("key.with.a.dot", "Special Value");
        assertEquals("Can retrieve directly (B)", "Special Value", bean.getMappedProperty("key.with.a.dot"));
        try {
            PropertyUtils.setNestedProperty(bean, "mappedProperty(key.with.a.dot)", "Updated Special Value");
            assertEquals("Check set via setNestedProperty (B)", "Updated Special Value", bean.getMappedProperty("key.with.a.dot"));
        } catch (final Exception e) {
            fail("Thew exception: " + e);
        }

        // -------- PropertyUtils.setNestedProperty() --------
        final TestBean testBean = new TestBean();
        bean.setMappedObjects("nested.property", testBean);
        assertEquals("Can retrieve directly (C)", "This is a string", testBean.getStringProperty());
        try {
            PropertyUtils.setNestedProperty(bean, "mappedObjects(nested.property).stringProperty", "Updated String Value");
            assertEquals("Check set via setNestedProperty (C)", "Updated String Value", testBean.getStringProperty());
        } catch (final Exception e) {
            fail("Thew exception: " + e);
        }

        // -------- PropertyUtils.setNestedProperty() --------
        bean.getNested().setMappedProperty("Mapped Key", "Nested Mapped Value");
        try {
            assertEquals("Can retrieve via getNestedProperty (D)", "Nested Mapped Value",
                    PropertyUtils.getNestedProperty(bean, "nested.mappedProperty(Mapped Key)"));
            PropertyUtils.setNestedProperty(bean, "nested.mappedProperty(Mapped Key)", "Updated Nested Mapped Value");
            assertEquals("Check set via setNestedProperty (D)", "Updated Nested Mapped Value",
                    PropertyUtils.getNestedProperty(bean, "nested.mappedProperty(Mapped Key)"));
        } catch (final Exception e) {
            fail("Thew exception: " + e);
        }
    }

    /**
     * Positive and negative tests on setMappedProperty valid arguments.
     */
    public void testSetMappedValues() {

        Object value = null;

        // Use explicit key argument

        try {
            value = PropertyUtils.getMappedProperty(bean, "mappedProperty", "Fourth Key");
            assertNull("Can not find fourth value", value);
        } catch (final Throwable t) {
            fail("Finding fourth value threw " + t);
        }

        try {
            PropertyUtils.setMappedProperty(bean, "mappedProperty", "Fourth Key", "Fourth Value");
        } catch (final Throwable t) {
            fail("Setting fourth value threw " + t);
        }

        try {
            value = PropertyUtils.getMappedProperty(bean, "mappedProperty", "Fourth Key");
            assertEquals("Can find fourth value", "Fourth Value", value);
        } catch (final Throwable t) {
            fail("Finding fourth value threw " + t);
        }

        // Use key expression with parentheses

        try {
            value = PropertyUtils.getMappedProperty(bean, "mappedProperty(Fifth Key)");
            assertNull("Can not find fifth value", value);
        } catch (final Throwable t) {
            fail("Finding fifth value threw " + t);
        }

        try {
            PropertyUtils.setMappedProperty(bean, "mappedProperty(Fifth Key)", "Fifth Value");
        } catch (final Throwable t) {
            fail("Setting fifth value threw " + t);
        }

        try {
            value = PropertyUtils.getMappedProperty(bean, "mappedProperty(Fifth Key)");
            assertEquals("Can find fifth value", "Fifth Value", value);
        } catch (final Throwable t) {
            fail("Finding fifth value threw " + t);
        }

        // Use key expression with dotted expression

        try {
            value = PropertyUtils.getNestedProperty(bean, "mapProperty.Sixth Key");
            assertNull("Can not find sixth value", value);
        } catch (final Throwable t) {
            fail("Finding fifth value threw " + t);
        }

        try {
            PropertyUtils.setNestedProperty(bean, "mapProperty.Sixth Key", "Sixth Value");
        } catch (final Throwable t) {
            fail("Setting sixth value threw " + t);
        }

        try {
            value = PropertyUtils.getNestedProperty(bean, "mapProperty.Sixth Key");
            assertEquals("Can find sixth value", "Sixth Value", value);
        } catch (final Throwable t) {
            fail("Finding sixth value threw " + t);
        }

    }

    /**
     * Corner cases on setNestedProperty invalid arguments.
     */
    public void testSetNestedArguments() {

        try {
            PropertyUtils.setNestedProperty(null, "stringProperty", "");
            fail("Should throw IllegalArgumentException 1");
        } catch (final IllegalArgumentException e) {
            // Expected response
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of IllegalArgumentException 1");
        }

        try {
            PropertyUtils.setNestedProperty(bean, null, "");
            fail("Should throw IllegalArgumentException 2");
        } catch (final IllegalArgumentException e) {
            // Expected response
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of IllegalArgumentException 2");
        }

    }

    /**
     * Test setNextedProperty on a boolean property.
     */
    public void testSetNestedBoolean() {

        try {
            final boolean oldValue = bean.getNested().getBooleanProperty();
            final boolean newValue = !oldValue;
            PropertyUtils.setNestedProperty(bean, "nested.booleanProperty", Boolean.valueOf(newValue));
            assertTrue("Matched new value", newValue == bean.getNested().getBooleanProperty());
        } catch (final IllegalAccessException e) {
            fail("IllegalAccessException");
        } catch (final IllegalArgumentException e) {
            fail("IllegalArgumentException");
        } catch (final InvocationTargetException e) {
            fail("InvocationTargetException");
        } catch (final NoSuchMethodException e) {
            fail("NoSuchMethodException");
        }

    }

    /**
     * Test setNestedProperty on a double property.
     */
    public void testSetNestedDouble() {

        try {
            final double oldValue = bean.getNested().getDoubleProperty();
            final double newValue = oldValue + 1.0;
            PropertyUtils.setNestedProperty(bean, "nested.doubleProperty", Double.valueOf(newValue));
            assertEquals("Matched new value", newValue, bean.getNested().getDoubleProperty(), 0.005);
        } catch (final IllegalAccessException e) {
            fail("IllegalAccessException");
        } catch (final IllegalArgumentException e) {
            fail("IllegalArgumentException");
        } catch (final InvocationTargetException e) {
            fail("InvocationTargetException");
        } catch (final NoSuchMethodException e) {
            fail("NoSuchMethodException");
        }

    }

    /**
     * Test setNestedProperty on a float property.
     */
    public void testSetNestedFloat() {

        try {
            final float oldValue = bean.getNested().getFloatProperty();
            final float newValue = oldValue + (float) 1.0;
            PropertyUtils.setNestedProperty(bean, "nested.floatProperty", Float.valueOf(newValue));
            assertEquals("Matched new value", newValue, bean.getNested().getFloatProperty(), (float) 0.005);
        } catch (final IllegalAccessException e) {
            fail("IllegalAccessException");
        } catch (final IllegalArgumentException e) {
            fail("IllegalArgumentException");
        } catch (final InvocationTargetException e) {
            fail("InvocationTargetException");
        } catch (final NoSuchMethodException e) {
            fail("NoSuchMethodException");
        }

    }

    /**
     * Test setNestedProperty on a int property.
     */
    public void testSetNestedInt() {

        try {
            final int oldValue = bean.getNested().getIntProperty();
            final int newValue = oldValue + 1;
            PropertyUtils.setNestedProperty(bean, "nested.intProperty", Integer.valueOf(newValue));
            assertEquals("Matched new value", newValue, bean.getNested().getIntProperty());
        } catch (final IllegalAccessException e) {
            fail("IllegalAccessException");
        } catch (final IllegalArgumentException e) {
            fail("IllegalArgumentException");
        } catch (final InvocationTargetException e) {
            fail("InvocationTargetException");
        } catch (final NoSuchMethodException e) {
            fail("NoSuchMethodException");
        }

    }

    /**
     * Test setNestedProperty on a long property.
     */
    public void testSetNestedLong() {

        try {
            final long oldValue = bean.getNested().getLongProperty();
            final long newValue = oldValue + 1;
            PropertyUtils.setNestedProperty(bean, "nested.longProperty", Long.valueOf(newValue));
            assertEquals("Matched new value", newValue, bean.getNested().getLongProperty());
        } catch (final IllegalAccessException e) {
            fail("IllegalAccessException");
        } catch (final IllegalArgumentException e) {
            fail("IllegalArgumentException");
        } catch (final InvocationTargetException e) {
            fail("InvocationTargetException");
        } catch (final NoSuchMethodException e) {
            fail("NoSuchMethodException");
        }

    }

    /**
     * Test setNestedProperty on a read-only String property.
     */
    public void testSetNestedReadOnly() {

        try {
            final String oldValue = bean.getNested().getWriteOnlyPropertyValue();
            final String newValue = oldValue + " Extra Value";
            PropertyUtils.setNestedProperty(bean, "nested.readOnlyProperty", newValue);
            fail("Should have thrown NoSuchMethodException");
        } catch (final IllegalAccessException e) {
            fail("IllegalAccessException");
        } catch (final IllegalArgumentException e) {
            fail("IllegalArgumentException");
        } catch (final InvocationTargetException e) {
            fail("InvocationTargetException");
        } catch (final NoSuchMethodException e) {
            // Correct result for this test
        }

    }

    /**
     * Test setNestedProperty on a short property.
     */
    public void testSetNestedShort() {

        try {
            final short oldValue = bean.getNested().getShortProperty();
            short newValue = oldValue;
            newValue++;
            PropertyUtils.setNestedProperty(bean, "nested.shortProperty", Short.valueOf(newValue));
            assertEquals("Matched new value", newValue, bean.getNested().getShortProperty());
        } catch (final IllegalAccessException e) {
            fail("IllegalAccessException");
        } catch (final IllegalArgumentException e) {
            fail("IllegalArgumentException");
        } catch (final InvocationTargetException e) {
            fail("InvocationTargetException");
        } catch (final NoSuchMethodException e) {
            fail("NoSuchMethodException");
        }

    }

    /**
     * Test setNestedProperty on a String property.
     */
    public void testSetNestedString() {

        try {
            final String oldValue = bean.getNested().getStringProperty();
            final String newValue = oldValue + " Extra Value";
            PropertyUtils.setNestedProperty(bean, "nested.stringProperty", newValue);
            assertEquals("Matched new value", newValue, bean.getNested().getStringProperty());
        } catch (final IllegalAccessException e) {
            fail("IllegalAccessException");
        } catch (final IllegalArgumentException e) {
            fail("IllegalArgumentException");
        } catch (final InvocationTargetException e) {
            fail("InvocationTargetException");
        } catch (final NoSuchMethodException e) {
            fail("NoSuchMethodException");
        }

    }

    /**
     * Test setNestedProperty on an unknown property name.
     */
    public void testSetNestedUnknown() {

        try {
            final String newValue = "New String Value";
            PropertyUtils.setNestedProperty(bean, "nested.unknown", newValue);
            fail("Should have thrown NoSuchMethodException");
        } catch (final IllegalAccessException e) {
            fail("IllegalAccessException");
        } catch (final IllegalArgumentException e) {
            fail("IllegalArgumentException");
        } catch (final InvocationTargetException e) {
            fail("InvocationTargetException");
        } catch (final NoSuchMethodException e) {
            // Correct result for this test
        }

    }

    /**
     * Test setNestedProperty on a write-only String property.
     */
    public void testSetNestedWriteOnly() {

        try {
            final String oldValue = bean.getNested().getWriteOnlyPropertyValue();
            final String newValue = oldValue + " Extra Value";
            PropertyUtils.setNestedProperty(bean, "nested.writeOnlyProperty", newValue);
            assertEquals("Matched new value", newValue, bean.getNested().getWriteOnlyPropertyValue());
        } catch (final IllegalAccessException e) {
            fail("IllegalAccessException");
        } catch (final IllegalArgumentException e) {
            fail("IllegalArgumentException");
        } catch (final InvocationTargetException e) {
            fail("InvocationTargetException");
        } catch (final NoSuchMethodException e) {
            fail("NoSuchMethodException");
        }

    }

    public void testSetNoGetter() throws Exception {
        final BetaBean bean = new BetaBean("Cedric");

        // test standard no getter
        bean.setNoGetterProperty("Sigma");
        assertEquals("BetaBean test failed", "Sigma", bean.getSecret());

        assertNotNull("Descriptor is null", PropertyUtils.getPropertyDescriptor(bean, "noGetterProperty"));

        BeanUtils.setProperty(bean, "noGetterProperty", "Omega");
        assertEquals("Cannot set no-getter property", "Omega", bean.getSecret());

        // test mapped no getter descriptor
        assertNotNull("Map Descriptor is null", PropertyUtils.getPropertyDescriptor(bean, "noGetterMappedProperty"));

        PropertyUtils.setMappedProperty(bean, "noGetterMappedProperty", "Epsilon", "Epsilon");
        assertEquals("Cannot set mapped no-getter property", "MAP:Epsilon", bean.getSecret());
    }

    /**
     * Test accessing a public sub-bean of a package scope bean
     */
    public void testSetPublicSubBean_of_PackageBean() {

        final PublicSubBean bean = new PublicSubBean();
        bean.setFoo("foo-start");
        bean.setBar("bar-start");

        // Set Foo
        try {
            PropertyUtils.setProperty(bean, "foo", "foo-updated");
        } catch (final Throwable t) {
            fail("setProperty(foo) threw " + t);
        }
        assertEquals("foo property", "foo-updated", bean.getFoo());

        // Set Bar
        try {
            PropertyUtils.setProperty(bean, "bar", "bar-updated");
        } catch (final Throwable t) {
            fail("setProperty(bar) threw " + t);
        }
        assertEquals("bar property", "bar-updated", bean.getBar());
    }

    /**
     * Corner cases on setSimpleProperty invalid arguments.
     */
    public void testSetSimpleArguments() {

        try {
            PropertyUtils.setSimpleProperty(null, "stringProperty", "");
            fail("Should throw IllegalArgumentException 1");
        } catch (final IllegalArgumentException e) {
            // Expected response
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of IllegalArgumentException 1");
        }

        try {
            PropertyUtils.setSimpleProperty(bean, null, "");
            fail("Should throw IllegalArgumentException 2");
        } catch (final IllegalArgumentException e) {
            // Expected response
        } catch (final Throwable t) {
            fail("Threw " + t + " instead of IllegalArgumentException 2");
        }

    }

    /**
     * Test setSimpleProperty on a boolean property.
     */
    public void testSetSimpleBoolean() {

        try {
            final boolean oldValue = bean.getBooleanProperty();
            final boolean newValue = !oldValue;
            PropertyUtils.setSimpleProperty(bean, "booleanProperty", Boolean.valueOf(newValue));
            assertTrue("Matched new value", newValue == bean.getBooleanProperty());
        } catch (final IllegalAccessException e) {
            fail("IllegalAccessException");
        } catch (final IllegalArgumentException e) {
            fail("IllegalArgumentException");
        } catch (final InvocationTargetException e) {
            fail("InvocationTargetException");
        } catch (final NoSuchMethodException e) {
            fail("NoSuchMethodException");
        }

    }

    /**
     * Test setSimpleProperty on a double property.
     */
    public void testSetSimpleDouble() {

        try {
            final double oldValue = bean.getDoubleProperty();
            final double newValue = oldValue + 1.0;
            PropertyUtils.setSimpleProperty(bean, "doubleProperty", Double.valueOf(newValue));
            assertEquals("Matched new value", newValue, bean.getDoubleProperty(), 0.005);
        } catch (final IllegalAccessException e) {
            fail("IllegalAccessException");
        } catch (final IllegalArgumentException e) {
            fail("IllegalArgumentException");
        } catch (final InvocationTargetException e) {
            fail("InvocationTargetException");
        } catch (final NoSuchMethodException e) {
            fail("NoSuchMethodException");
        }

    }

    /**
     * Test setSimpleProperty on a float property.
     */
    public void testSetSimpleFloat() {

        try {
            final float oldValue = bean.getFloatProperty();
            final float newValue = oldValue + (float) 1.0;
            PropertyUtils.setSimpleProperty(bean, "floatProperty", Float.valueOf(newValue));
            assertEquals("Matched new value", newValue, bean.getFloatProperty(), (float) 0.005);
        } catch (final IllegalAccessException e) {
            fail("IllegalAccessException");
        } catch (final IllegalArgumentException e) {
            fail("IllegalArgumentException");
        } catch (final InvocationTargetException e) {
            fail("InvocationTargetException");
        } catch (final NoSuchMethodException e) {
            fail("NoSuchMethodException");
        }

    }

    /**
     * Negative test setSimpleProperty on an indexed property.
     */
    public void testSetSimpleIndexed() {

        try {
            PropertyUtils.setSimpleProperty(bean, "stringIndexed[0]", "New String Value");
            fail("Should have thrown IllegalArgumentException");
        } catch (final IllegalAccessException e) {
            fail("IllegalAccessException");
        } catch (final IllegalArgumentException e) {
            // Correct result for this test
        } catch (final InvocationTargetException e) {
            fail("InvocationTargetException");
        } catch (final NoSuchMethodException e) {
            fail("NoSuchMethodException");
        }

    }

    /**
     * Test setSimpleProperty on a int property.
     */
    public void testSetSimpleInt() {

        try {
            final int oldValue = bean.getIntProperty();
            final int newValue = oldValue + 1;
            PropertyUtils.setSimpleProperty(bean, "intProperty", Integer.valueOf(newValue));
            assertEquals("Matched new value", newValue, bean.getIntProperty());
        } catch (final IllegalAccessException e) {
            fail("IllegalAccessException");
        } catch (final IllegalArgumentException e) {
            fail("IllegalArgumentException");
        } catch (final InvocationTargetException e) {
            fail("InvocationTargetException");
        } catch (final NoSuchMethodException e) {
            fail("NoSuchMethodException");
        }

    }

    /**
     * Test setSimpleProperty on a long property.
     */
    public void testSetSimpleLong() {

        try {
            final long oldValue = bean.getLongProperty();
            final long newValue = oldValue + 1;
            PropertyUtils.setSimpleProperty(bean, "longProperty", Long.valueOf(newValue));
            assertEquals("Matched new value", newValue, bean.getLongProperty());
        } catch (final IllegalAccessException e) {
            fail("IllegalAccessException");
        } catch (final IllegalArgumentException e) {
            fail("IllegalArgumentException");
        } catch (final InvocationTargetException e) {
            fail("InvocationTargetException");
        } catch (final NoSuchMethodException e) {
            fail("NoSuchMethodException");
        }

    }

    /**
     * Negative test setSimpleProperty on a nested property.
     */
    public void testSetSimpleNested() {

        try {
            PropertyUtils.setSimpleProperty(bean, "nested.stringProperty", "New String Value");
            fail("Should have thrown IllegalArgumentException");
        } catch (final IllegalAccessException e) {
            fail("IllegalAccessException");
        } catch (final IllegalArgumentException e) {
            // Correct result for this test
        } catch (final InvocationTargetException e) {
            fail("InvocationTargetException");
        } catch (final NoSuchMethodException e) {
            fail("NoSuchMethodException");
        }

    }

    /**
     * Test setSimpleProperty on a read-only String property.
     */
    public void testSetSimpleReadOnly() {

        try {
            final String oldValue = bean.getWriteOnlyPropertyValue();
            final String newValue = oldValue + " Extra Value";
            PropertyUtils.setSimpleProperty(bean, "readOnlyProperty", newValue);
            fail("Should have thrown NoSuchMethodException");
        } catch (final IllegalAccessException e) {
            fail("IllegalAccessException");
        } catch (final IllegalArgumentException e) {
            fail("IllegalArgumentException");
        } catch (final InvocationTargetException e) {
            fail("InvocationTargetException");
        } catch (final NoSuchMethodException e) {
            // Correct result for this test
            assertEquals("Property 'readOnlyProperty' has no setter method in class '" + bean.getClass() + "'", e.getMessage());
        }

    }

    /**
     * Test setSimpleProperty on a short property.
     */
    public void testSetSimpleShort() {

        try {
            final short oldValue = bean.getShortProperty();
            short newValue = oldValue;
            newValue++;
            PropertyUtils.setSimpleProperty(bean, "shortProperty", Short.valueOf(newValue));
            assertEquals("Matched new value", newValue, bean.getShortProperty());
        } catch (final IllegalAccessException e) {
            fail("IllegalAccessException");
        } catch (final IllegalArgumentException e) {
            fail("IllegalArgumentException");
        } catch (final InvocationTargetException e) {
            fail("InvocationTargetException");
        } catch (final NoSuchMethodException e) {
            fail("NoSuchMethodException");
        }

    }

    /**
     * Test setSimpleProperty on a String property.
     */
    public void testSetSimpleString() {

        try {
            final String oldValue = bean.getStringProperty();
            final String newValue = oldValue + " Extra Value";
            PropertyUtils.setSimpleProperty(bean, "stringProperty", newValue);
            assertEquals("Matched new value", newValue, bean.getStringProperty());
        } catch (final IllegalAccessException e) {
            fail("IllegalAccessException");
        } catch (final IllegalArgumentException e) {
            fail("IllegalArgumentException");
        } catch (final InvocationTargetException e) {
            fail("InvocationTargetException");
        } catch (final NoSuchMethodException e) {
            fail("NoSuchMethodException");
        }

    }

    /**
     * Test setSimpleProperty on an unknown property name.
     */
    public void testSetSimpleUnknown() {

        try {
            final String newValue = "New String Value";
            PropertyUtils.setSimpleProperty(bean, "unknown", newValue);
            fail("Should have thrown NoSuchMethodException");
        } catch (final IllegalAccessException e) {
            fail("IllegalAccessException");
        } catch (final IllegalArgumentException e) {
            fail("IllegalArgumentException");
        } catch (final InvocationTargetException e) {
            fail("InvocationTargetException");
        } catch (final NoSuchMethodException e) {
            // Correct result for this test
            assertEquals("Unknown property 'unknown' on class '" + bean.getClass() + "'", e.getMessage());
        }

    }

    /**
     * Test setSimpleProperty on a write-only String property.
     */
    public void testSetSimpleWriteOnly() {

        try {
            final String oldValue = bean.getWriteOnlyPropertyValue();
            final String newValue = oldValue + " Extra Value";
            PropertyUtils.setSimpleProperty(bean, "writeOnlyProperty", newValue);
            assertEquals("Matched new value", newValue, bean.getWriteOnlyPropertyValue());
        } catch (final IllegalAccessException e) {
            fail("IllegalAccessException");
        } catch (final IllegalArgumentException e) {
            fail("IllegalArgumentException");
        } catch (final InvocationTargetException e) {
            fail("InvocationTargetException");
        } catch (final NoSuchMethodException e) {
            fail("NoSuchMethodException");
        }

    }

    /**
     * When a bean has a null property which is reference by the standard access language, this should throw a NestedNullException.
     */
    public void testThrowNestedNull() throws Exception {
        final NestedTestBean nestedBean = new NestedTestBean("base");
        // don't init!

        try {
            PropertyUtils.getProperty(nestedBean, "simpleBeanProperty.indexedProperty[0]");
            fail("NestedNullException not thrown");
        } catch (final NestedNullException e) {
            // that's what we wanted!
        }
    }
}
