| /* | 
 |  * 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 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" | 
 |     }; | 
 |  | 
 |     /** | 
 |      * 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", | 
 |     }; | 
 |  | 
 |  | 
 |  | 
 |     /** | 
 |      * Constructs a new instance of this test case. | 
 |      * | 
 |      * @param name Name of the test case | 
 |      */ | 
 |     public PropertyUtilsTestCase(final String name) { | 
 |  | 
 |         super(name); | 
 |  | 
 |     } | 
 |  | 
 |  | 
 |  | 
 |     /** | 
 |      * 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[] { | 
 |                 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(); | 
 |     } | 
 |  | 
 |     /** | 
 |      * Creates the tests included in this test suite. | 
 |      */ | 
 |     public static Test suite() { | 
 |  | 
 |         return new TestSuite(PropertyUtilsTestCase.class); | 
 |  | 
 |     } | 
 |  | 
 |     /** | 
 |      * 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(); | 
 |     } | 
 |  | 
 |  | 
 |  | 
 |     /** | 
 |      * 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", new Float((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", new Short((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]); | 
 |  | 
 |     } | 
 |  | 
 |     /** | 
 |      * 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'", | 
 |                      new Float((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'", | 
 |                      new Short((short) 987), map.get("shortProperty")); | 
 |         assertEquals("Value of 'stringProperty'", | 
 |                      "This is a string", | 
 |                      (String) map.get("stringProperty")); | 
 |  | 
 |     } | 
 |  | 
 |     /** | 
 |      * 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"); | 
 |         } | 
 |  | 
 |     } | 
 |  | 
 |     /** | 
 |      * 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><property-name></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 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"); | 
 |  | 
 |     } | 
 |  | 
 |     /** | 
 |      * 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"); | 
 |         } | 
 |  | 
 |     } | 
 |  | 
 |     /** | 
 |      * 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"); | 
 |         } | 
 |  | 
 |     } | 
 |  | 
 |     /** | 
 |      * 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"); | 
 |         } | 
 |  | 
 |     } | 
 |  | 
 |     /** | 
 |      * Test getting an indexed value out of a multi-dimensional array | 
 |      */ | 
 |     public void testGetIndexedArray() { | 
 |         final String[] firstArray = new String[] {"FIRST-1", "FIRST-2", "FIRST-3"}; | 
 |         final String[] secondArray = new String[] {"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 = new String[] {"FIRST-1", "FIRST-2", "FIRST-3"}; | 
 |         final String[] secondArray = new String[] {"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 + ""); | 
 |         } | 
 |     } | 
 |  | 
 |     /** | 
 |      * 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 = new String[] {"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 | 
 |         } | 
 |  | 
 |     } | 
 |  | 
 |     /** | 
 |      * 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! | 
 |         } | 
 |     } | 
 |  | 
 |     /** | 
 |      * 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 = new int[0]; | 
 |         final String[] stringArray = new String[0]; | 
 |  | 
 |         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); | 
 |     } | 
 |  | 
 |     /** | 
 |      * 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); | 
 |  | 
 |     } | 
 |  | 
 |     /** | 
 |      * 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() ); | 
 |         } | 
 |  | 
 |     } | 
 |  | 
 |     /** | 
 |      * 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); | 
 |         } | 
 |     } | 
 |  | 
 |     /** | 
 |      * 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()); | 
 |  | 
 |     } | 
 |  | 
 |     /** | 
 |      * 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 = new String[] {"FIRST-1", "FIRST-2", "FIRST-3"}; | 
 |         final String[] secondArray = new String[] {"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 = new String[] {"FIRST-1", "FIRST-2", "FIRST-3"}; | 
 |         final String[] secondArray = new String[] {"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 = new String[] {"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")); | 
 |     } | 
 |  | 
 |     /** | 
 |      * 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); | 
 |         } | 
 |  | 
 |     } | 
 |  | 
 |     /** | 
 |      * 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); | 
 |         } | 
 |     } | 
 |  | 
 |     /** | 
 |      * 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", | 
 |                     new Boolean(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", | 
 |                     new Float(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", | 
 |                     new Short(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"); | 
 |         } | 
 |  | 
 |     } | 
 |  | 
 |     /** | 
 |      * 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", | 
 |                     new Boolean(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", | 
 |                     new Float(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", | 
 |                     new Short(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"); | 
 |         } | 
 |  | 
 |     } | 
 |  | 
 |  | 
 |  | 
 |     /** | 
 |      * 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"); | 
 |         } | 
 |  | 
 |     } | 
 |  | 
 |     /** | 
 |      * 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); | 
 |             } | 
 |  | 
 |         } | 
 |  | 
 |     } | 
 |  | 
 |     /** | 
 |      * 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); | 
 |  | 
 |         } | 
 |  | 
 |     } | 
 |  | 
 |     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()); | 
 |     } | 
 |  | 
 |     /** 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()); | 
 |     } | 
 |  | 
 |     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()); | 
 |     } | 
 |  | 
 |     /** | 
 |      * 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); | 
 |         } | 
 |     } | 
 |  | 
 |     /** | 
 |      * 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(); | 
 |     } | 
 |  | 
 |     /** | 
 |      * 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()); | 
 |     } | 
 |  | 
 |     /** | 
 |      * 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)"); | 
 |     } | 
 |  | 
 |     /** | 
 |      * 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); | 
 |         } | 
 |     } | 
 |  | 
 |     /** | 
 |      * 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); | 
 |     } | 
 |  | 
 |     /** | 
 |      * 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; | 
 |     } | 
 |  | 
 |     /** | 
 |      * 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); | 
 |     } | 
 |  | 
 |     /** | 
 |      * 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); | 
 |     } | 
 |  | 
 |     /** | 
 |      * Tries to add a null BeanIntrospector. | 
 |      */ | 
 |     public void testAddBeanIntrospectorNull() { | 
 |         try { | 
 |             PropertyUtils.addBeanIntrospector(null); | 
 |             fail("Could add null BeanIntrospector!"); | 
 |         } catch (final IllegalArgumentException iex) { | 
 |             // ok | 
 |         } | 
 |     } | 
 |  | 
 |     /** | 
 |      * 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); | 
 |     } | 
 | } |