[fest-reflect] 01/02: Imported Upstream version 1.4.1

Andreas Tille tille at debian.org
Sun Apr 26 05:45:47 UTC 2015


This is an automated email from the git hooks/post-receive script.

tille pushed a commit to branch master
in repository fest-reflect.

commit 55147ad358df486d7c16a33aa69cf22561652db1
Author: Andreas Tille <tille at debian.org>
Date:   Sun Apr 26 07:35:15 2015 +0200

    Imported Upstream version 1.4.1
---
 .gitignore                                         |   5 +
 LICENSE.txt                                        | 202 +++++++++++
 pom.xml                                            |  62 ++++
 .../org/fest/reflect/beanproperty/Invoker.java     | 140 ++++++++
 .../fest/reflect/beanproperty/PropertyName.java    | 104 ++++++
 .../fest/reflect/beanproperty/PropertyType.java    |  67 ++++
 .../fest/reflect/beanproperty/PropertyTypeRef.java |  69 ++++
 .../org/fest/reflect/beanproperty/package.html     |  41 +++
 .../java/org/fest/reflect/constructor/Invoker.java |  95 ++++++
 .../fest/reflect/constructor/ParameterTypes.java   |  58 ++++
 .../org/fest/reflect/constructor/TargetType.java   |  69 ++++
 .../java/org/fest/reflect/constructor/package.html |  41 +++
 .../java/org/fest/reflect/core/Reflection.java     | 260 +++++++++++++++
 src/main/java/org/fest/reflect/core/package.html   |  78 +++++
 .../fest/reflect/exception/ReflectionError.java    |  42 +++
 .../java/org/fest/reflect/exception/package.html   |  24 ++
 .../org/fest/reflect/field/DecoratedInvoker.java   | 146 ++++++++
 .../java/org/fest/reflect/field/FieldName.java     | 111 +++++++
 .../java/org/fest/reflect/field/FieldType.java     |  77 +++++
 .../java/org/fest/reflect/field/FieldTypeRef.java  |  80 +++++
 src/main/java/org/fest/reflect/field/Invoker.java  | 302 +++++++++++++++++
 .../org/fest/reflect/field/StaticFieldName.java    | 102 ++++++
 .../org/fest/reflect/field/StaticFieldType.java    |  64 ++++
 .../org/fest/reflect/field/StaticFieldTypeRef.java |  69 ++++
 .../decorator/DecoratorInvocationHandler.java      |  82 +++++
 .../reflect/field/decorator/PostDecorator.java     |  48 +++
 .../fest/reflect/field/decorator/PreDecorator.java |  47 +++
 .../field/decorator/RuntimeExceptionShield.java    |  61 ++++
 src/main/java/org/fest/reflect/field/package.html  |  47 +++
 .../java/org/fest/reflect/innerclass/Invoker.java  |  59 ++++
 .../reflect/innerclass/StaticInnerClassName.java   |  81 +++++
 .../java/org/fest/reflect/innerclass/package.html  |  37 +++
 src/main/java/org/fest/reflect/method/Invoker.java | 134 ++++++++
 .../java/org/fest/reflect/method/MethodName.java   | 125 +++++++
 .../fest/reflect/method/MethodParameterTypes.java  |  70 ++++
 .../org/fest/reflect/method/MethodReturnType.java  |  79 +++++
 .../fest/reflect/method/MethodReturnTypeRef.java   |  74 +++++
 .../org/fest/reflect/method/StaticMethodName.java  | 123 +++++++
 .../reflect/method/StaticMethodParameterTypes.java |  76 +++++
 .../reflect/method/StaticMethodReturnType.java     |  85 +++++
 .../reflect/method/StaticMethodReturnTypeRef.java  |  75 +++++
 src/main/java/org/fest/reflect/method/package.html |  61 ++++
 .../java/org/fest/reflect/reference/TypeRef.java   |  54 +++
 .../java/org/fest/reflect/reference/package.html   |  25 ++
 src/main/java/org/fest/reflect/type/Type.java      | 113 +++++++
 .../java/org/fest/reflect/type/TypeLoader.java     |  99 ++++++
 src/main/java/org/fest/reflect/type/package.html   |  37 +++
 .../java/org/fest/reflect/util/Accessibles.java    |  76 +++++
 .../java/org/fest/reflect/util/Throwables.java     |  41 +++
 src/main/java/org/fest/reflect/util/package.html   |  24 ++
 src/main/javadoc/overview.html                     |  17 +
 src/site/changes.xml                               | 109 ++++++
 src/site/resources/images/fest-reflect.png         | Bin 0 -> 24936 bytes
 src/site/site.vm                                   | 369 +++++++++++++++++++++
 src/site/site.xml                                  |  25 ++
 src/site/xdoc/index.xml                            |  14 +
 src/test/java/org/fest/reflect/Jedi.java           | 114 +++++++
 src/test/java/org/fest/reflect/Person.java         |  57 ++++
 .../fest/reflect/beanproperty/Property_Test.java   | 165 +++++++++
 .../fest/reflect/constructor/Constructor_Test.java | 107 ++++++
 .../core/FEST68_CatchingWrongExceptions_Test.java  |  60 ++++
 .../org/fest/reflect/core/Reflection_Test.java     |  81 +++++
 .../reflect/field/FieldDecoratorCombinedTest.java  | 145 ++++++++
 .../field/FieldDecoratorIgnoreExceptionTest.java   | 204 ++++++++++++
 ...FieldDecoratorReturningDecoratorResultTest.java | 214 ++++++++++++
 .../org/fest/reflect/field/FieldDecoratorTest.java | 184 ++++++++++
 .../org/fest/reflect/field/Field_field_Test.java   | 157 +++++++++
 .../fest/reflect/field/Field_staticField_Test.java | 151 +++++++++
 .../org/fest/reflect/field/NestedFieldTest.java    | 197 +++++++++++
 .../decorator/TestRuntimeExceptionShield.java      |  79 +++++
 .../org/fest/reflect/innerclass/OuterClass.java    |  42 +++
 .../reflect/innerclass/StaticInnerClass_Test.java  |  84 +++++
 .../fest/reflect/method/Method_method_Test.java    | 208 ++++++++++++
 .../reflect/method/Method_staticMethod_Test.java   | 174 ++++++++++
 src/test/java/org/fest/reflect/type/Type_Test.java | 120 +++++++
 .../org/fest/reflect/util/ExpectedFailures.java    |  42 +++
 76 files changed, 7260 insertions(+)

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..ecd131a
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+.classpath
+.project
+/bin
+/target
+.settings
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..4cbbad2
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd ">
+
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.easytesting</groupId>
+  <artifactId>fest-reflect</artifactId>
+  <version>1.4.1</version>
+  <name>FEST Reflection</name>
+  <description>Fluent Interface that simplifies usage of Java Reflection</description>
+  <inceptionYear>2007</inceptionYear>
+  <url>http://fest.easytesting.org/reflect</url>
+  <parent>
+    <groupId>org.easytesting</groupId>
+    <artifactId>fest</artifactId>
+    <version>1.0.15</version>
+  </parent>
+  <mailingLists>
+    <mailingList>
+      <name>Easy Testing Group</name>
+      <post>http://groups.google.com/group/easytesting</post>
+      <subscribe>http://groups.google.com/group/easytesting</subscribe>
+      <unsubscribe>http://groups.google.com/group/easytesting</unsubscribe>
+    </mailingList>
+  </mailingLists>
+  <scm>
+    <developerConnection>scm:git:git at github.com:alexruiz/fest-reflect.git</developerConnection>
+    <connection>scm:git:git://github.com/alexruiz/fest-reflect.git</connection>
+    <url>https://github.com/alexruiz/fest-reflect</url>
+  </scm>
+  <issueManagement>
+    <system>JIRA</system>
+    <url>http://jira.codehaus.org/browse/FEST</url>
+  </issueManagement>
+  <dependencies>
+    <dependency>
+      <groupId>org.easytesting</groupId>
+      <artifactId>fest-util</artifactId>
+      <version>1.2.4</version>
+      <type>jar</type>
+    </dependency>
+    <dependency>
+      <groupId>org.easytesting</groupId>
+      <artifactId>fest-test</artifactId>
+      <version>1.2</version>
+      <type>jar</type>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>4.7</version>
+      <type>jar</type>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-all</artifactId>
+      <scope>test</scope>
+      <version>1.9.0</version>
+    </dependency>
+  </dependencies>
+</project>
diff --git a/src/main/java/org/fest/reflect/beanproperty/Invoker.java b/src/main/java/org/fest/reflect/beanproperty/Invoker.java
new file mode 100644
index 0000000..1039418
--- /dev/null
+++ b/src/main/java/org/fest/reflect/beanproperty/Invoker.java
@@ -0,0 +1,140 @@
+/*
+ * Created on Nov 23, 2009
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2009 the original author or authors.
+ */
+package org.fest.reflect.beanproperty;
+
+import static org.fest.util.Strings.concat;
+import static org.fest.util.Strings.quote;
+
+import java.beans.BeanInfo;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+
+import org.fest.reflect.exception.ReflectionError;
+import org.fest.reflect.field.StaticFieldName;
+import org.fest.reflect.field.StaticFieldType;
+import org.fest.reflect.reference.TypeRef;
+
+/**
+ * Understands the use of instrospection to access a property from a JavaBean.
+ * <p>
+ * The following is an example of proper usage of this class:
+ * 
+ * <pre>
+ *   // Retrieves the value of the property "name"
+ *   String name = {@link org.fest.reflect.core.Reflection#property(String) property}("name").{@link PropertyName#ofType(Class) ofType}(String.class).{@link PropertyType#in(Object) in}(person).{@link Invoker#get() get}();
+ *
+ *   // Sets the value of the property "name" to "Yoda"
+ *   {@link org.fest.reflect.core.Reflection#property(String) property}("name").{@link PropertyName#ofType(Class) ofType}(String.class).{@link PropertyType#in(Object) in}(person).{@link Invoker#set(Object) set}("Yoda");
+ *
+ *   // Retrieves the value of the static property "count"
+ *   int count = {@link org.fest.reflect.core.Reflection#staticField(String) staticField}("count").{@link StaticFieldName#ofType(Class) ofType}(int.class).{@link StaticFieldType#in(Class) in}(Person.class).{@link Invoker#get() get}();
+ *
+ *   // Sets the value of the static property "count" to 3
+ *   {@link org.fest.reflect.core.Reflection#staticField(String) property}("count").{@link StaticFieldName#ofType(Class) ofType}(int.class).{@link StaticFieldType#in(Class) in}(Person.class).{@link Invoker#set(Object) set}(3);
+ * </pre>
+ * </p>
+ * 
+ * @param <T> the declared type for the property to access.
+ * 
+ * @author Alex Ruiz
+ * 
+ * @since 1.2
+ */
+public final class Invoker<T> {
+
+  static <T> Invoker<T> newInvoker(String name, TypeRef<T> expectedType, Object target) {
+    return createInvoker(name, expectedType.rawType(), target);
+  }
+
+  static <T> Invoker<T> newInvoker(String name, Class<T> expectedType, Object target) {
+    return createInvoker(name, expectedType, target);
+  }
+
+  private static <T> Invoker<T> createInvoker(String name, Class<?> expectedType, Object target) {
+    PropertyDescriptor descriptor = descriptorForProperty(name, target);
+    verifyCorrectType(name, target, expectedType, descriptor);
+    return new Invoker<T>(name, target, descriptor);
+  }
+
+  private static PropertyDescriptor descriptorForProperty(String propertyName, Object target) {
+    BeanInfo beanInfo = null;
+    Class<?> type = target.getClass();
+    try {
+      beanInfo = Introspector.getBeanInfo(type);
+    } catch (Exception e) {
+      throw new ReflectionError(concat("Unable to get BeanInfo for type ", type.getName()), e);
+    }
+    for (PropertyDescriptor d : beanInfo.getPropertyDescriptors())
+      if (propertyName.equals(d.getName())) return d;
+    throw new ReflectionError(concat("Unable to find property ", quote(propertyName), " in ", type.getName()));
+  }
+
+  static void verifyCorrectType(String name, Object target, Class<?> expectedType, PropertyDescriptor descriptor) {
+    Class<?> actualType = descriptor.getPropertyType();
+    if (!expectedType.isAssignableFrom(actualType)) throw incorrectPropertyType(name, target, actualType, expectedType);
+  }
+
+  private static ReflectionError incorrectPropertyType(String name, Object target, Class<?> actual, Class<?> expected) {
+    String typeName = target.getClass().getName();
+    String msg = concat("The type of the property ", quote(name), " in ", typeName, " should be <", expected.getName(),
+        "> but was <", actual.getName(), ">");
+    throw new ReflectionError(msg);
+  }
+
+  private final String propertyName;
+  private final Object target;
+  private final PropertyDescriptor descriptor;
+
+  private Invoker(String propertyName, Object target, PropertyDescriptor descriptor) {
+    this.propertyName = propertyName;
+    this.target = target;
+    this.descriptor = descriptor;
+  }
+
+  /**
+   * Sets a value in the property managed by this class.
+   * @param value the value to set.
+   * @throws ReflectionError if the given value cannot be set.
+   */
+  public void set(T value) {
+    try {
+      descriptor.getWriteMethod().invoke(target, value);
+    } catch (Exception e) {
+      throw new ReflectionError(concat("Unable to update the value in property ", quote(propertyName)), e);
+    }
+  }
+
+  /**
+   * Returns the value of the property managed by this class.
+   * @return the value of the property managed by this class.
+   * @throws ReflectionError if the value of the property cannot be retrieved.
+   */
+  @SuppressWarnings("unchecked")
+  public T get() {
+    try {
+      return (T) descriptor.getReadMethod().invoke(target);
+    } catch (Exception e) {
+      throw new ReflectionError(concat("Unable to obtain the value in property " + quote(propertyName)), e);
+    }
+  }
+
+  /**
+   * Returns the "real" property managed by this class.
+   * @return the "real" property managed by this class.
+   */
+  public PropertyDescriptor info() {
+    return descriptor;
+  }
+}
diff --git a/src/main/java/org/fest/reflect/beanproperty/PropertyName.java b/src/main/java/org/fest/reflect/beanproperty/PropertyName.java
new file mode 100644
index 0000000..483eca5
--- /dev/null
+++ b/src/main/java/org/fest/reflect/beanproperty/PropertyName.java
@@ -0,0 +1,104 @@
+/*
+ * Created on Nov 23, 2009
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2009 the original author or authors.
+ */
+package org.fest.reflect.beanproperty;
+
+import static org.fest.reflect.beanproperty.PropertyType.newPropertyType;
+import static org.fest.reflect.beanproperty.PropertyTypeRef.newPropertyTypeRef;
+import static org.fest.util.Strings.isEmpty;
+
+import org.fest.reflect.reference.TypeRef;
+
+/**
+ * Understands the name of a property to access using Bean Introspection.
+ * <p>
+ * The following is an example of proper usage of this class:
+ * 
+ * <pre>
+ *   // Retrieves the value of the property "name"
+ *   String name = {@link org.fest.reflect.core.Reflection#property(String) property}("name").{@link PropertyName#ofType(Class) ofType}(String.class).{@link PropertyType#in(Object) in}(person).{@link Invoker#get() get}();
+ *
+ *   // Sets the value of the property "name" to "Yoda"
+ *   {@link org.fest.reflect.core.Reflection#property(String) property}("name").{@link PropertyName#ofType(Class) ofType}(String.class).{@link PropertyType#in(Object) in}(person).{@link Invoker#set(Object) set}("Yoda");
+ *
+ *   // Retrieves the value of the property "powers"
+ *   List<String> powers = {@link org.fest.reflect.core.Reflection#property(String) property}("powers").{@link #ofType(TypeRef) ofType}(new {@link TypeRef TypeRef}<List<String>>() {}).{@link PropertyTypeRef#in(Object) in}(jedi).{@link Invoker#get() get}();
+ *
+ *   // Sets the value of the property "powers"
+ *   List<String> powers = new ArrayList<String>();
+ *   powers.add("heal");
+ *   {@link org.fest.reflect.core.Reflection#property(String) property}("powers").{@link #ofType(TypeRef) ofType}(new {@link TypeRef TypeRef}<List<String>>() {}).{@link PropertyTypeRef#in(Object) in}(jedi).{@link Invoker#set(Object) set}(powers);
+ * </pre>
+ * </p>
+ * 
+ * @author Alex Ruiz
+ * 
+ * @since 1.2
+ */
+public final class PropertyName {
+
+  /**
+   * Creates a new <code>{@link PropertyName}</code>: the starting point of the fluent interface for accessing properties using
+   * Bean Introspection.
+   * @param name the name of the property to access using Bean Introspection.
+   * @return the created <code>PropertyName</code>.
+   * @throws NullPointerException if the given name is <code>null</code>.
+   * @throws IllegalArgumentException if the given name is empty.
+   */
+  public static PropertyName startPropertyAccess(String name) {
+    validateIsNotNullOrEmpty(name);
+    return new PropertyName(name);
+  }
+
+  private static void validateIsNotNullOrEmpty(String name) {
+    if (name == null) throw new NullPointerException("The name of the property to access should not be null");
+    if (isEmpty(name)) throw new IllegalArgumentException("The name of the property to access should not be empty");
+  }
+
+  private final String name;
+
+  private PropertyName(String name) {
+    this.name = name;
+  }
+
+  /**
+   * Sets the type of the property to access.
+   * @param <T> the generic type of the property type.
+   * @param type the type of the property to access.
+   * @return a recipient for the property type.
+   * @throws NullPointerException if the given type is <code>null</code>.
+   */
+  public <T> PropertyType<T> ofType(Class<T> type) {
+    return newPropertyType(name, type);
+  }
+
+  /**
+   * Sets the type reference of the property to access. This method reduces casting when the type of the property to access uses
+   * generics.
+   * <p>
+   * For example:
+   * 
+   * <pre>
+   *   List<String> powers = {@link org.fest.reflect.core.Reflection#property(String) property}("powers").{@link #ofType(TypeRef) ofType}(new {@link TypeRef TypeRef}<List<String>>() {}).{@link PropertyTypeRef#in(Object) in}(jedi).{@link Invoker#get() get}();
+   * </pre>
+   * </p>
+   * @param <T> the generic type of the property type.
+   * @param type the type of the property to access.
+   * @return a recipient for the property type.
+   * @throws NullPointerException if the given type reference is <code>null</code>.
+   */
+  public <T> PropertyTypeRef<T> ofType(TypeRef<T> type) {
+    return newPropertyTypeRef(name, type);
+  }
+}
\ No newline at end of file
diff --git a/src/main/java/org/fest/reflect/beanproperty/PropertyType.java b/src/main/java/org/fest/reflect/beanproperty/PropertyType.java
new file mode 100644
index 0000000..91a0ed7
--- /dev/null
+++ b/src/main/java/org/fest/reflect/beanproperty/PropertyType.java
@@ -0,0 +1,67 @@
+/*
+ * Created on Nov 23, 2009
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2009 the original author or authors.
+ */
+package org.fest.reflect.beanproperty;
+
+import static org.fest.reflect.beanproperty.Invoker.newInvoker;
+
+import org.fest.reflect.exception.ReflectionError;
+
+/**
+ * Understands the type of a property to access using Bean Instrospection.
+ * <p>
+ * The following is an example of proper usage of this class:
+ * 
+ * <pre>
+ *   // Retrieves the value of the property "name"
+ *   String name = {@link org.fest.reflect.core.Reflection#property(String) property}("name").{@link PropertyName#ofType(Class) ofType}(String.class).{@link PropertyType#in(Object) in}(person).{@link Invoker#get() get}();
+ *
+ *   // Sets the value of the property "name" to "Yoda"
+ *   {@link org.fest.reflect.core.Reflection#property(String) property}("name").{@link PropertyName#ofType(Class) ofType}(String.class).{@link PropertyType#in(Object) in}(person).{@link Invoker#set(Object) set}("Yoda");
+ * </pre>
+ * </p>
+ * 
+ * @param <T> the generic type of the property.
+ * 
+ * @author Alex Ruiz
+ * 
+ * @since 1.2
+ */
+public class PropertyType<T> {
+
+  static <T> PropertyType<T> newPropertyType(String name, Class<T> type) {
+    if (type == null) throw new NullPointerException("The type of the property to access should not be null");
+    return new PropertyType<T>(name, type);
+  }
+
+  private final String name;
+  private final Class<T> type;
+
+  private PropertyType(String name, Class<T> type) {
+    this.name = name;
+    this.type = type;
+  }
+
+  /**
+   * Returns a new property invoker. A property invoker is capable of accessing (read/write) the underlying property.
+   * @param target the object containing the property of interest.
+   * @return the created property invoker.
+   * @throws NullPointerException if the given target is <code>null</code>.
+   * @throws ReflectionError if a property with a matching name and type cannot be found.
+   */
+  public Invoker<T> in(Object target) {
+    if (target == null) throw new NullPointerException("Target should not be null");
+    return newInvoker(name, type, target);
+  }
+}
\ No newline at end of file
diff --git a/src/main/java/org/fest/reflect/beanproperty/PropertyTypeRef.java b/src/main/java/org/fest/reflect/beanproperty/PropertyTypeRef.java
new file mode 100644
index 0000000..becd81c
--- /dev/null
+++ b/src/main/java/org/fest/reflect/beanproperty/PropertyTypeRef.java
@@ -0,0 +1,69 @@
+/*
+ * Created on Nov 23, 2009
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2009 the original author or authors.
+ */
+package org.fest.reflect.beanproperty;
+
+import static org.fest.reflect.beanproperty.Invoker.newInvoker;
+
+import org.fest.reflect.exception.ReflectionError;
+import org.fest.reflect.reference.TypeRef;
+
+/**
+ * Understands the type of a property to access using Bean Instrospection. This implementation supports Java generics.
+ * <p>
+ * The following is an example of proper usage of this class:
+ * 
+ * <pre>
+ *   // Retrieves the value of the property "powers"
+ *   List<String> powers = {@link org.fest.reflect.core.Reflection#property(String) property}("powers").{@link PropertyName#ofType(TypeRef) ofType}(new {@link TypeRef TypeRef}<List<String>>() {}).{@link #in(Object) in}(jedi).{@link Invoker#get() get}();
+ *
+ *   // Sets the value of the property "powers"
+ *   List<String> powers = new ArrayList<String>();
+ *   powers.add("heal");
+ *   {@link org.fest.reflect.core.Reflection#property(String) property}("powers").{@link PropertyName#ofType(TypeRef) ofType}(new {@link TypeRef TypeRef}<List<String>>() {}).{@link #in(Object) in}(jedi).{@link Invoker#set(Object) set}(powers);
+ * </pre>
+ * </p>
+ * 
+ * @param <T> the generic type of the property.
+ * 
+ * @author Alex Ruiz
+ * 
+ * @since 1.2
+ */
+public class PropertyTypeRef<T> {
+
+  static <T> PropertyTypeRef<T> newPropertyTypeRef(String name, TypeRef<T> type) {
+    if (type == null) throw new NullPointerException("The type reference of the property to access should not be null");
+    return new PropertyTypeRef<T>(name, type);
+  }
+
+  private final TypeRef<T> type;
+  private final String name;
+
+  private PropertyTypeRef(String name, TypeRef<T> type) {
+    this.name = name;
+    this.type = type;
+  }
+
+  /**
+   * Returns a new property invoker. A property invoker is capable of accessing (read/write) the underlying property.
+   * @param target the object containing the property of interest.
+   * @return the created property invoker.
+   * @throws NullPointerException if the given target is <code>null</code>.
+   * @throws ReflectionError if a property with a matching name and type cannot be found.
+   */
+  public Invoker<T> in(Object target) {
+    return newInvoker(name, type, target);
+  }
+}
\ No newline at end of file
diff --git a/src/main/java/org/fest/reflect/beanproperty/package.html b/src/main/java/org/fest/reflect/beanproperty/package.html
new file mode 100644
index 0000000..e3ac600
--- /dev/null
+++ b/src/main/java/org/fest/reflect/beanproperty/package.html
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<!-- 
+Licensed 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.
+
+Copyright @2009 the original author or authors.
+ -->
+</head>
+<body bgcolor="white">
+<p>
+Provides a "fluent" API 
+for property access via the Bean Instrospection API.
+</p>
+<p>
+<strong>Note:</strong> Classes in this package are not intended to be used directly. To use them, you need to use the
+class <code>{@link org.fest.reflect.core.Reflection org.fest.reflect.core.Reflection}</code>.
+</p>
+<p>
+Here are some examples:
+<pre>
+   // import static {@link org.fest.reflect.core.Reflection org.fest.reflect.core.Reflection}.*;
+
+   // Retrieves the value of the property "name"
+   String name = {@link org.fest.reflect.core.Reflection#property(String) property}("name").{@link org.fest.reflect.beanproperty.PropertyName#ofType(Class) ofType}(String.class).{@link org.fest.reflect.beanproperty.PropertyType#in(Object) in}(person).{@link org.fest.reflect.beanproperty.Invoker#get() get}();
+   
+   // Sets the value of the property "name" to "Yoda"
+   {@link org.fest.reflect.core.Reflection#property(String) property}("name").{@link org.fest.reflect.beanproperty.PropertyName#ofType(Class) ofType}(String.class).{@link org.fest.reflect.beanproperty.PropertyType#in(Object) in}(person).{@link org.fest.reflect.beanproperty.Invoker#set(Object) set}("Yoda");
+</pre>
+</p>
+</body>
+</html>
\ No newline at end of file
diff --git a/src/main/java/org/fest/reflect/constructor/Invoker.java b/src/main/java/org/fest/reflect/constructor/Invoker.java
new file mode 100644
index 0000000..d4e56bf
--- /dev/null
+++ b/src/main/java/org/fest/reflect/constructor/Invoker.java
@@ -0,0 +1,95 @@
+/*
+ * Created on Oct 31, 2006
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2006-2009 the original author or authors.
+ */
+package org.fest.reflect.constructor;
+
+import static org.fest.reflect.util.Accessibles.makeAccessible;
+import static org.fest.reflect.util.Accessibles.setAccessibleIgnoringExceptions;
+import static org.fest.reflect.util.Throwables.targetOf;
+import static org.fest.util.Strings.concat;
+
+import java.lang.reflect.Constructor;
+import java.util.Arrays;
+
+import org.fest.reflect.exception.ReflectionError;
+
+/**
+ * Understands the invocation of a constructor via Java Reflection.
+ * @param <T> the class in which the constructor is declared.
+ *          <p>
+ *          The following is an example of proper usage of the classes in this package:
+ * 
+ * <pre>
+ *   // Equivalent to call 'new Person()'
+ *   Person p = {@link org.fest.reflect.core.Reflection#constructor() constructor}().{@link TargetType#in in}(Person.class).{@link #newInstance newInstance}();
+ *
+ *   // Equivalent to call 'new Person("Yoda")'
+ *   Person p = {@link org.fest.reflect.core.Reflection#constructor() constructor}().{@link TargetType#withParameterTypes(Class...) withParameterTypes}(String.class).{@link ParameterTypes#in(Class) in}(Person.class).{@link #newInstance newInstance}("Yoda");
+ * </pre>
+ *          </p>
+ * 
+ * @author Alex Ruiz
+ * @author Yvonne Wang
+ */
+public final class Invoker<T> {
+
+  public static <T> Invoker<T> newInvoker(Class<T> target, Class<?>... parameterTypes) {
+    Constructor<T> constructor = constructor(target, parameterTypes);
+    return new Invoker<T>(constructor);
+  }
+
+  private static <T> Constructor<T> constructor(Class<T> target, Class<?>... parameterTypes) {
+    try {
+      return target.getDeclaredConstructor(parameterTypes);
+    } catch (Exception e) {
+      throw new ReflectionError(concat("Unable to find constructor in type ", target.getName(), " with parameter types ",
+          Arrays.toString(parameterTypes)), e);
+    }
+  }
+
+  private final Constructor<T> constructor;
+
+  private Invoker(Constructor<T> constructor) {
+    this.constructor = constructor;
+  }
+
+  /**
+   * Creates a new instance of <code>T</code> by calling a constructor with the given arguments.
+   * @param args the arguments to pass to the constructor (can be zero or more).
+   * @return the created instance of <code>T</code>.
+   * @throws ReflectionError if a new instance cannot be created.
+   */
+  public T newInstance(Object... args) {
+    boolean accessible = constructor.isAccessible();
+    try {
+      makeAccessible(constructor);
+      T newInstance = constructor.newInstance(args);
+      return newInstance;
+    } catch (Throwable t) {
+      Throwable cause = targetOf(t);
+      if (cause instanceof RuntimeException) throw (RuntimeException) cause;
+      throw new ReflectionError("Unable to create a new object from the enclosed constructor", cause);
+    } finally {
+      setAccessibleIgnoringExceptions(constructor, accessible);
+    }
+  }
+
+  /**
+   * Returns the "real" constructor managed by this class.
+   * @return the "real" constructor managed by this class.
+   */
+  public Constructor<T> info() {
+    return constructor;
+  }
+}
diff --git a/src/main/java/org/fest/reflect/constructor/ParameterTypes.java b/src/main/java/org/fest/reflect/constructor/ParameterTypes.java
new file mode 100644
index 0000000..7b77c15
--- /dev/null
+++ b/src/main/java/org/fest/reflect/constructor/ParameterTypes.java
@@ -0,0 +1,58 @@
+/*
+ * Created on Aug 17, 2006
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2006-2009 the original author or authors.
+ */
+package org.fest.reflect.constructor;
+
+import static org.fest.reflect.constructor.Invoker.newInvoker;
+
+/**
+ * Understands the parameter types for the constructor to invoke.
+ * <p>
+ * The following is an example of proper usage of the classes in this package:
+ * 
+ * <pre>
+ *   // Equivalent to call 'new Person()'
+ *   Person p = {@link org.fest.reflect.core.Reflection#constructor() constructor}().{@link TargetType#in in}(Person.class).{@link Invoker#newInstance newInstance}();
+ *
+ *   // Equivalent to call 'new Person("Yoda")'
+ *   Person p = {@link org.fest.reflect.core.Reflection#constructor() constructor}().{@link TargetType#withParameterTypes(Class...) withParameterTypes}(String.class).{@link ParameterTypes#in(Class) in}(Person.class).{@link Invoker#newInstance newInstance}("Yoda");
+ * </pre>
+ * </p>
+ * 
+ * @author Alex Ruiz
+ * @author Yvonne Wang
+ */
+public final class ParameterTypes {
+
+  static ParameterTypes newParameterTypes(Class<?>[] parameterTypes) {
+    if (parameterTypes == null) throw new NullPointerException("The array of parameter types should not be null");
+    return new ParameterTypes(parameterTypes);
+  }
+
+  private final Class<?>[] parameterTypes;
+
+  private ParameterTypes(Class<?>[] parameterTypes) {
+    this.parameterTypes = parameterTypes;
+  }
+
+  /**
+   * Creates a new constructor invoker.
+   * @param <T> the generic type of the class containing the constructor to invoke.
+   * @param target the the type of object that the constructor invoker will create.
+   * @return the created constructor invoker.
+   */
+  public <T> Invoker<T> in(Class<T> target) {
+    return newInvoker(target, parameterTypes);
+  }
+}
\ No newline at end of file
diff --git a/src/main/java/org/fest/reflect/constructor/TargetType.java b/src/main/java/org/fest/reflect/constructor/TargetType.java
new file mode 100644
index 0000000..4d4a167
--- /dev/null
+++ b/src/main/java/org/fest/reflect/constructor/TargetType.java
@@ -0,0 +1,69 @@
+/*
+ * Created on Aug 17, 2006
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2006-2009 the original author or authors.
+ */
+package org.fest.reflect.constructor;
+
+import static org.fest.reflect.constructor.Invoker.newInvoker;
+import static org.fest.reflect.constructor.ParameterTypes.newParameterTypes;
+
+/**
+ * Understands the type of object that the constructor will create.
+ * <p>
+ * The following is an example of proper usage of the classes in this package:
+ * 
+ * <pre>
+ *   // Equivalent to call 'new Person()'
+ *   Person p = {@link org.fest.reflect.core.Reflection#constructor() constructor}().{@link TargetType#in in}(Person.class).{@link Invoker#newInstance newInstance}();
+ *
+ *   // Equivalent to call 'new Person("Yoda")'
+ *   Person p = {@link org.fest.reflect.core.Reflection#constructor() constructor}().{@link TargetType#withParameterTypes(Class...) withParameterTypes}(String.class).{@link ParameterTypes#in(Class) in}(Person.class).{@link Invoker#newInstance newInstance}("Yoda");
+ * </pre>
+ * </p>
+ * 
+ * @author Alex Ruiz
+ * @author Yvonne Wang
+ */
+public final class TargetType {
+
+  /**
+   * Creates a new </code>{@link TargetType}</code>.
+   * @return the created <code>TargetType</code>.
+   */
+  public static TargetType startConstructorAccess() {
+    return new TargetType();
+  }
+
+  private TargetType() {}
+
+  /**
+   * Creates a new constructor invoker.
+   * @param <T> the generic type of the class containing the constructor to invoke.
+   * @param target the the type of object that the constructor invoker will create.
+   * @return the created constructor invoker.
+   */
+  public <T> Invoker<T> in(Class<T> target) {
+    return newInvoker(target);
+  }
+
+  /**
+   * Specifies the parameter types for the constructor to invoke. This method call is optional if the constructor to call does not
+   * accept arguments.
+   * @param parameterTypes the types of the parameters to pass to the constructor.
+   * @return the created parameter type holder.
+   * @throws NullPointerException if the given array is <code>null</code>.
+   */
+  public ParameterTypes withParameterTypes(Class<?>... parameterTypes) {
+    return newParameterTypes(parameterTypes);
+  }
+}
\ No newline at end of file
diff --git a/src/main/java/org/fest/reflect/constructor/package.html b/src/main/java/org/fest/reflect/constructor/package.html
new file mode 100644
index 0000000..495a686
--- /dev/null
+++ b/src/main/java/org/fest/reflect/constructor/package.html
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<!-- 
+Licensed 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.
+
+Copyright @2007-2009 the original author or authors.
+ -->
+</head>
+<body bgcolor="white">
+<p>
+Provides a "fluent" API for
+constructor invocation via the Java Reflection API.
+</p>
+<p>
+<strong>Note:</strong> Classes in this package are not intended to be used directly. To use them, you need to use the
+class <code>{@link org.fest.reflect.core.Reflection org.fest.reflect.core.Reflection}</code>.
+</p>
+<p>
+Here are some examples:
+<pre>
+   // import static {@link org.fest.reflect.core.Reflection org.fest.reflect.core.Reflection}.*;
+
+   // Equivalent to call 'new Person()'
+   Person p = {@link org.fest.reflect.core.Reflection#constructor() constructor}().{@link org.fest.reflect.constructor.TargetType#in in}(Person.class).{@link org.fest.reflect.constructor.Invoker#newInstance(Object...) newInstance}();
+   
+   // Equivalent to call 'new Person("Yoda")'
+   Person p = {@link org.fest.reflect.core.Reflection#constructor() constructor}().{@link org.fest.reflect.constructor.TargetType#withParameterTypes(Class...) withParameterTypes}(String.class).{@link org.fest.reflect.constructor.ParameterTypes#in(Class) in}(Person.class).{@link org.fest.reflect.constructor.Invoker#newInstance(Object...) newInstance}("Yoda");
+</pre>
+</p>
+</body>
+</html>
\ No newline at end of file
diff --git a/src/main/java/org/fest/reflect/core/Reflection.java b/src/main/java/org/fest/reflect/core/Reflection.java
new file mode 100644
index 0000000..bd66f03
--- /dev/null
+++ b/src/main/java/org/fest/reflect/core/Reflection.java
@@ -0,0 +1,260 @@
+/*
+ * Created on Oct 31, 2006
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2006-2009 the original author or authors.
+ */
+package org.fest.reflect.core;
+
+import static org.fest.reflect.beanproperty.PropertyName.startPropertyAccess;
+import static org.fest.reflect.constructor.TargetType.startConstructorAccess;
+import static org.fest.reflect.field.FieldName.beginFieldAccess;
+import static org.fest.reflect.field.StaticFieldName.beginStaticFieldAccess;
+import static org.fest.reflect.innerclass.StaticInnerClassName.startStaticInnerClassAccess;
+import static org.fest.reflect.method.MethodName.startMethodAccess;
+import static org.fest.reflect.method.StaticMethodName.startStaticMethodAccess;
+import static org.fest.reflect.type.Type.newType;
+
+import org.fest.reflect.beanproperty.PropertyName;
+import org.fest.reflect.beanproperty.PropertyType;
+import org.fest.reflect.constructor.TargetType;
+import org.fest.reflect.field.FieldName;
+import org.fest.reflect.field.FieldTypeRef;
+import org.fest.reflect.field.StaticFieldName;
+import org.fest.reflect.field.StaticFieldType;
+import org.fest.reflect.field.StaticFieldTypeRef;
+import org.fest.reflect.innerclass.StaticInnerClassName;
+import org.fest.reflect.method.Invoker;
+import org.fest.reflect.method.MethodName;
+import org.fest.reflect.method.MethodReturnTypeRef;
+import org.fest.reflect.method.StaticMethodName;
+import org.fest.reflect.method.StaticMethodReturnTypeRef;
+import org.fest.reflect.reference.TypeRef;
+import org.fest.reflect.type.Type;
+
+/**
+ * Understands the entry point for the classes in this package.
+ * <p>
+ * The following is an example of proper usage of the classes in this package:
+ * 
+ * <pre>
+ *   // Loads the class 'org.republic.Jedi'
+ *   Class<?> jediType = {@link org.fest.reflect.core.Reflection#type(String) type}("org.republic.Jedi").{@link Type#load() load}();
+ *
+ *   // Loads the class 'org.republic.Jedi' as 'org.republic.Person' (Jedi extends Person)
+ *   Class<Person> jediType = {@link org.fest.reflect.core.Reflection#type(String) type}("org.republic.Jedi").{@link Type#loadAs(Class) loadAs}(Person.class);
+ *
+ *   // Loads the class 'org.republic.Jedi' using a custom class loader
+ *   Class<?> jediType = {@link org.fest.reflect.core.Reflection#type(String) type}("org.republic.Jedi").{@link Type#withClassLoader(ClassLoader) withClassLoader}(myClassLoader).{@link org.fest.reflect.type.TypeLoader#load() load}();
+ *
+ *   // Gets the inner class 'Master' in the declaring class 'Jedi':
+ *   Class<?> masterClass = {@link org.fest.reflect.core.Reflection#staticInnerClass(String) staticInnerClass}("Master").{@link org.fest.reflect.innerclass.StaticInnerClassName#in(Class) in}(Jedi.class).{@link org.fest.reflect.innerclass.Invoker#get() get}();
+ *
+ *   // Equivalent to call 'new Person()'
+ *   Person p = {@link org.fest.reflect.core.Reflection#constructor() constructor}().{@link TargetType#in in}(Person.class).{@link org.fest.reflect.constructor.Invoker#newInstance(Object...) newInstance}();
+ *
+ *   // Equivalent to call 'new Person("Yoda")'
+ *   Person p = {@link org.fest.reflect.core.Reflection#constructor() constructor}().{@link TargetType#withParameterTypes(Class...) withParameterTypes}(String.class).{@link org.fest.reflect.constructor.ParameterTypes#in(Class) in}(Person.class).{@link org.fest.reflect.constructor.Invoker#newInstance(Object...) newInstance}("Yoda");
+ *
+ *   // Retrieves the value of the field "name"
+ *   String name = {@link org.fest.reflect.core.Reflection#field(String) field}("name").{@link org.fest.reflect.field.FieldName#ofType(Class) ofType}(String.class).{@link org.fest.reflect.field.FieldType#in(Object) in}(person).{@link org.fest.reflect.field.Invoker#get() get}();
+ *
+ *   // Sets the value of the field "name" to "Yoda"
+ *   {@link org.fest.reflect.core.Reflection#field(String) field}("name").{@link org.fest.reflect.field.FieldName#ofType(Class) ofType}(String.class).{@link org.fest.reflect.field.FieldType#in(Object) in}(person).{@link org.fest.reflect.field.Invoker#set(Object) set}("Yoda");
+ *
+ *   // Retrieves the value of the field "powers"
+ *   List<String> powers = {@link org.fest.reflect.core.Reflection#field(String) field}("powers").{@link FieldName#ofType(TypeRef) ofType}(new {@link TypeRef TypeRef}<List<String>>() {}).{@link FieldTypeRef#in(Object) in}(jedi).{@link org.fest.reflect.field.Invoker#get() get}();
+ *
+ *   // Equivalent to call 'person.setName("Luke")'
+ *   {@link org.fest.reflect.core.Reflection#method(String) method}("setName").{@link org.fest.reflect.method.MethodName#withParameterTypes(Class...) withParameterTypes}(String.class)
+ *                    .{@link org.fest.reflect.method.MethodParameterTypes#in(Object) in}(person)
+ *                    .{@link org.fest.reflect.method.Invoker#invoke(Object...) invoke}("Luke");
+ *
+ *   // Equivalent to call 'jedi.getPowers()'
+ *   List<String> powers = {@link org.fest.reflect.core.Reflection#method(String) method}("getPowers").{@link MethodName#withReturnType(TypeRef) withReturnType}(new {@link TypeRef TypeRef}<List<String>>() {})
+ *                                            .{@link MethodReturnTypeRef#in(Object) in}(person)
+ *                                            .{@link Invoker#invoke(Object...) invoke}();
+ *
+ *   // Retrieves the value of the static field "count" in Person.class
+ *   int count = {@link org.fest.reflect.core.Reflection#staticField(String) staticField}("count").{@link StaticFieldName#ofType(Class) ofType}(int.class).{@link StaticFieldType#in(Class) in}(Person.class).{@link org.fest.reflect.field.Invoker#get() get}();
+ *
+ *   // Sets the value of the static field "count" to 3 in Person.class
+ *   {@link org.fest.reflect.core.Reflection#staticField(String) staticField}("count").{@link StaticFieldName#ofType(Class) ofType}(int.class).{@link StaticFieldType#in(Class) in}(Person.class).{@link org.fest.reflect.field.Invoker#set(Object) set}(3);
+ *
+ *   // Retrieves the value of the static field "commonPowers" in Jedi.class
+ *   List<String> commmonPowers = {@link org.fest.reflect.core.Reflection#staticField(String) staticField}("commonPowers").{@link StaticFieldName#ofType(TypeRef) ofType}(new {@link TypeRef TypeRef}<List<String>>() {}).{@link StaticFieldTypeRef#in(Class) in}(Jedi.class).{@link org.fest.reflect.field.Invoker#get() get}();
+ *
+ *   // Equivalent to call 'person.concentrate()'
+ *   {@link org.fest.reflect.core.Reflection#method(String) method}("concentrate").{@link org.fest.reflect.method.MethodName#in(Object) in}(person).{@link org.fest.reflect.method.Invoker#invoke(Object...) invoke}();
+ *
+ *   // Equivalent to call 'person.getName()'
+ *   String name = {@link org.fest.reflect.core.Reflection#method(String) method}("getName").{@link org.fest.reflect.method.MethodName#withReturnType(Class) withReturnType}(String.class)
+ *                                  .{@link org.fest.reflect.method.MethodReturnType#in(Object) in}(person)
+ *                                  .{@link org.fest.reflect.method.Invoker#invoke(Object...) invoke}();
+ *
+ *   // Equivalent to call 'Jedi.setCommonPower("Jump")'
+ *   {@link org.fest.reflect.core.Reflection#staticMethod(String) staticMethod}("setCommonPower").{@link org.fest.reflect.method.StaticMethodName#withParameterTypes(Class...) withParameterTypes}(String.class)
+ *                                 .{@link org.fest.reflect.method.StaticMethodParameterTypes#in(Class) in}(Jedi.class)
+ *                                 .{@link org.fest.reflect.method.Invoker#invoke(Object...) invoke}("Jump");
+ *
+ *   // Equivalent to call 'Jedi.addPadawan()'
+ *   {@link org.fest.reflect.core.Reflection#staticMethod(String) staticMethod}("addPadawan").{@link org.fest.reflect.method.StaticMethodName#in(Class) in}(Jedi.class).{@link org.fest.reflect.method.Invoker#invoke(Object...) invoke}();
+ *
+ *   // Equivalent to call 'Jedi.commonPowerCount()'
+ *   String name = {@link org.fest.reflect.core.Reflection#staticMethod(String) staticMethod}("commonPowerCount").{@link org.fest.reflect.method.StaticMethodName#withReturnType(Class) withReturnType}(String.class)
+ *                                                 .{@link org.fest.reflect.method.StaticMethodReturnType#in(Class) in}(Jedi.class)
+ *                                                 .{@link org.fest.reflect.method.Invoker#invoke(Object...) invoke}();
+ *
+ *   // Equivalent to call 'Jedi.getCommonPowers()'
+ *   List<String> powers = {@link org.fest.reflect.core.Reflection#staticMethod(String) staticMethod}("getCommonPowers").{@link StaticMethodName#withReturnType(TypeRef) withReturnType}(new {@link TypeRef TypeRef}<List<String>>() {})
+ *                                                        .{@link StaticMethodReturnTypeRef#in(Class) in}(Jedi.class)
+ *                                                        .{@link Invoker#invoke(Object...) invoke}();
+ *
+ *   // Retrieves the value of the property "name"
+ *   String name = {@link org.fest.reflect.core.Reflection#property(String) property}("name").{@link PropertyName#ofType(Class) ofType}(String.class).{@link PropertyType#in(Object) in}(person).{@link org.fest.reflect.beanproperty.Invoker#get() get}();
+ *
+ *   // Sets the value of the property "name" to "Yoda"
+ *   {@link org.fest.reflect.core.Reflection#property(String) property}("name").{@link PropertyName#ofType(Class) ofType}(String.class).{@link PropertyType#in(Object) in}(person).{@link org.fest.reflect.beanproperty.Invoker#set(Object) set}("Yoda");
+ * </pre>
+ * </p>
+ * 
+ * @author Alex Ruiz
+ * @author Yvonne Wang
+ * @author Ivan Hristov
+ */
+public final class Reflection {
+
+  /**
+   * Starting point of the fluent interface for loading a class dynamically.
+   * @param name the name of the class to load.
+   * @return the starting point of the method chain.
+   * @throws NullPointerException if the given name is <code>null</code>.
+   * @throws IllegalArgumentException if the given name is empty.
+   * @since 1.1
+   */
+  public static Type type(String name) {
+    return newType(name);
+  }
+
+  /**
+   * Starting point of the fluent interface for accessing static inner class via reflection.
+   * @param name the name of the static inner class to access.
+   * @return the starting point of the method chain.
+   * @throws NullPointerException if the given name is <code>null</code>.
+   * @throws IllegalArgumentException if the given name is empty.
+   * @since 1.1
+   */
+  public static StaticInnerClassName staticInnerClass(String name) {
+    return startStaticInnerClassAccess(name);
+  }
+
+  /**
+   * Starting point of the fluent interface for accessing fields via reflection.<br>
+   * Nested field are supported with dot notation, e.g. <code>"person.address.street"</code>.
+   * <p>
+   * Let's look how it works on an example :
+   * 
+   * <pre>
+   * Let's say we have the following simple service:
+   * 
+   * public class BusinessService {
+   *   private NotificationService notificationService = new NotificationService();
+   *   //... logic goes here
+   * }
+   *  
+   * Where NotificationService is defined as follows:
+   * 
+   * public class NotificationService {
+   *   private Logger logger = new Logger();
+   *   private IClientStatusDao clientStatusDao = new ClientStatusDao();
+   *   //... logic goes here
+   * }
+   * 
+   * And our ClientStatusDao looks like:
+   * 
+   * public class ClientStatusDao implements IClientStatusDao {
+   *   private final Session session = new SessionImpl();
+   *    //... logic goes here
+   * }
+   *     
+   * Let's say we want to change the {@code logger} field of {@code NotificationService} within our instance of {@code BusinessService}, we can do this:
+   *  
+   *   field("notificationService.logger").ofType(Logger.class).in(businessService).set(loggerMock);
+   *  
+   * You can also set the deeply nested {@code session} field within {@code ClientStatusDao} like this:
+   * 
+   *   field("notificationService.clientStatusDao.session").ofType(Session.class).in(businessService).set(sessionMock);
+   * </pre>
+   * 
+   * @param name the name of the field to access.
+   * @return the starting point of the method chain.
+   * @throws NullPointerException if the given name is <code>null</code>.
+   * @throws IllegalArgumentException if the given name is empty.
+   */
+  public static FieldName field(String name) {
+    return beginFieldAccess(name);
+  }
+
+  /**
+   * Starting point of the fluent interface for accessing static fields via reflection.
+   * @param name the name of the static field to access.
+   * @return the starting point of the method chain.
+   * @throws NullPointerException if the given name is <code>null</code>.
+   * @throws IllegalArgumentException if the given name is empty.
+   */
+  public static StaticFieldName staticField(String name) {
+    return beginStaticFieldAccess(name);
+  }
+
+  /**
+   * Starting point of the fluent interface for invoking methods via reflection.
+   * @param name the name of the method to invoke.
+   * @return the starting point of the method chain.
+   * @throws NullPointerException if the given name is <code>null</code>.
+   * @throws IllegalArgumentException if the given name is empty.
+   */
+  public static MethodName method(String name) {
+    return startMethodAccess(name);
+  }
+
+  /**
+   * Starting point of the fluent interface for invoking static methods via reflection.
+   * @param name the name of the static method to invoke.
+   * @return the starting point of the static method chain.
+   * @throws NullPointerException if the given name is <code>null</code>.
+   * @throws IllegalArgumentException if the given name is empty.
+   */
+  public static StaticMethodName staticMethod(String name) {
+    return startStaticMethodAccess(name);
+  }
+
+  /**
+   * Starting point of the fluent interface for invoking constructors via reflection.
+   * @return the starting point of the method chain.
+   */
+  public static TargetType constructor() {
+    return startConstructorAccess();
+  }
+
+  /**
+   * Starting point of the fluent interface for accessing properties via Bean Introspection.
+   * @param name the name of the property to access.
+   * @return the starting point of the method chain.
+   * @throws NullPointerException if the given name is <code>null</code>.
+   * @throws IllegalArgumentException if the given name is empty.
+   * @since 1.2
+   */
+  public static PropertyName property(String name) {
+    return startPropertyAccess(name);
+  }
+
+  private Reflection() {}
+}
diff --git a/src/main/java/org/fest/reflect/core/package.html b/src/main/java/org/fest/reflect/core/package.html
new file mode 100644
index 0000000..bedf38e
--- /dev/null
+++ b/src/main/java/org/fest/reflect/core/package.html
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<!-- 
+Licensed 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.
+
+Copyright @2007-2009 the original author or authors.
+ -->
+</head>
+<body bgcolor="white">
+<p>
+Provides a "fluent" API that
+makes usage of the Java Reflection API easier and improves code readability.
+</p>
+<p>
+Here are some examples:
+<pre>
+   // import static {@link org.fest.reflect.core.Reflection org.fest.reflect.core.Reflection}.*;
+
+   // Loads the class 'org.republic.Jedi'
+   Class<?> jediType = {@link org.fest.reflect.core.Reflection#type(String) type}("org.republic.Jedi").{@link org.fest.reflect.type.Type#load() load}();
+   
+   // Loads the class 'org.republic.Jedi' as 'org.republic.Person' (Jedi extends Person)
+   Class<Person> jediType = {@link org.fest.reflect.core.Reflection#type(String) type}("org.republic.Jedi").{@link org.fest.reflect.type.Type#loadAs(Class) loadAs}(Person.class);
+
+   // Loads the class 'org.republic.Jedi' using a custom class loader
+   Class<?> jediType = {@link org.fest.reflect.core.Reflection#type(String) type}("org.republic.Jedi").{@link org.fest.reflect.type.Type#withClassLoader(ClassLoader) withClassLoader}(myClassLoader).{@link org.fest.reflect.type.TypeLoader#load() load}();
+
+   // Gets the inner class 'Master' in the declaring class 'Jedi':
+   Class<?> masterClass = {@link org.fest.reflect.core.Reflection#staticInnerClass(String) staticInnerClass}("Master").{@link org.fest.reflect.innerclass.StaticInnerClassName#in(Class) in}(Jedi.class).{@link org.fest.reflect.innerclass.Invoker#get() get}();
+
+   // Equivalent to call 'new Person()'
+   Person p = {@link org.fest.reflect.core.Reflection#constructor() constructor}().{@link org.fest.reflect.constructor.TargetType#in in}(Person.class).{@link org.fest.reflect.constructor.Invoker#newInstance(Object...) newInstance}();
+   
+   // Equivalent to call 'new Person("Yoda")'
+   Person p = {@link org.fest.reflect.core.Reflection#constructor() constructor}().{@link org.fest.reflect.constructor.TargetType#withParameterTypes(Class...) withParameterTypes}(String.class).{@link org.fest.reflect.constructor.ParameterTypes#in(Class) in}(Person.class).{@link org.fest.reflect.constructor.Invoker#newInstance(Object...) newInstance}("Yoda");
+ 
+   // Retrieves the value of the field "name"
+   String name = {@link org.fest.reflect.core.Reflection#field(String) field}("name").{@link org.fest.reflect.field.FieldName#ofType(Class) ofType}(String.class).{@link org.fest.reflect.field.FieldType#in(Object) in}(person).{@link org.fest.reflect.field.Invoker#get() get}();
+   
+   // Sets the value of the field 'name' to "Yoda"
+   {@link org.fest.reflect.core.Reflection#field(String) field}("name").{@link org.fest.reflect.field.FieldName#ofType(Class) ofType}(String.class).{@link org.fest.reflect.field.FieldType#in(Object) in}(person).{@link org.fest.reflect.field.Invoker#set(Object) set}("Yoda");
+   
+   // Equivalent to call 'jedi.getPowers()'
+   List<String> powers = {@link org.fest.reflect.core.Reflection#method(String) method}("getPowers").{@link org.fest.reflect.method.MethodName#withReturnType(org.fest.reflect.reference.TypeRef) withReturnType}(new {@link org.fest.reflect.reference.TypeRef TypeRef}<List<String>>() {})
+                                            .{@link org.fest.reflect.method.MethodReturnTypeRef#in(Object) in}(person)
+                                            .{@link org.fest.reflect.method.Invoker#invoke(Object...) invoke}();   
+
+   // Equivalent to call 'person.setName("Luke")'
+   {@link org.fest.reflect.core.Reflection#method(String) method}("setName").{@link org.fest.reflect.method.MethodName#withParameterTypes(Class...) withParameterTypes}(String.class)
+                    .{@link org.fest.reflect.method.MethodParameterTypes#in(Object) in}(person)
+                    .{@link org.fest.reflect.method.Invoker#invoke(Object...) invoke}("Luke");
+ 
+   // Equivalent to call 'person.concentrate()'
+   {@link org.fest.reflect.core.Reflection#method(String) method}("concentrate").{@link org.fest.reflect.method.MethodName#in(Object) in}(person).{@link org.fest.reflect.method.Invoker#invoke(Object...) invoke}();
+   
+   // Equivalent to call 'person.getName()'
+   String name = {@link org.fest.reflect.core.Reflection#method(String) method}("getName").{@link org.fest.reflect.method.MethodName#withReturnType(Class) withReturnType}(String.class)
+                                  .{@link org.fest.reflect.method.MethodReturnType#in(Object) in}(person)
+                                  .{@link org.fest.reflect.method.Invoker#invoke(Object...) invoke}();   
+                                                  
+   // Equivalent to call 'Jedi.getCommonPowers()'
+   List<String> powers = {@link org.fest.reflect.core.Reflection#staticMethod(String) staticMethod}("getCommonPowers").{@link org.fest.reflect.method.StaticMethodName#withReturnType(org.fest.reflect.reference.TypeRef) withReturnType}(new {@link org.fest.reflect.reference.TypeRef TypeRef}<List<String>>() {})
+                                                        .{@link org.fest.reflect.method.StaticMethodReturnTypeRef#in(Class) in}(Jedi.class)
+                                                        .{@link org.fest.reflect.method.Invoker#invoke(Object...) invoke}();   
+</pre>
+</p>
+</body>
+</html>
\ No newline at end of file
diff --git a/src/main/java/org/fest/reflect/exception/ReflectionError.java b/src/main/java/org/fest/reflect/exception/ReflectionError.java
new file mode 100644
index 0000000..a2c2447
--- /dev/null
+++ b/src/main/java/org/fest/reflect/exception/ReflectionError.java
@@ -0,0 +1,42 @@
+/*
+ * Created on Nov 16, 2006
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2006-2009 the original author or authors.
+ */
+package org.fest.reflect.exception;
+
+/**
+ * Understands an error raised when using reflection.
+ * 
+ * @author Alex Ruiz
+ */
+public final class ReflectionError extends RuntimeException {
+
+  private static final long serialVersionUID = 1L;
+
+  /**
+   * Creates a new <code>{@link ReflectionError}</code>.
+   * @param message the detail message.
+   */
+  public ReflectionError(String message) {
+    super(message);
+  }
+
+  /**
+   * Creates a new <code>{@link ReflectionError}</code>.
+   * @param message the detail message.
+   * @param cause the cause of the exception.
+   */
+  public ReflectionError(String message, Throwable cause) {
+    super(message, cause);
+  }
+}
diff --git a/src/main/java/org/fest/reflect/exception/package.html b/src/main/java/org/fest/reflect/exception/package.html
new file mode 100644
index 0000000..d7f9308
--- /dev/null
+++ b/src/main/java/org/fest/reflect/exception/package.html
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<!-- 
+Licensed 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.
+
+Copyright @2007-2009 the original author or authors.
+ -->
+</head>
+<body bgcolor="white">
+<p>
+Exceptions used in the FEST-Reflect module.
+</p>
+</body>
+</html>
\ No newline at end of file
diff --git a/src/main/java/org/fest/reflect/field/DecoratedInvoker.java b/src/main/java/org/fest/reflect/field/DecoratedInvoker.java
new file mode 100644
index 0000000..41b8d36
--- /dev/null
+++ b/src/main/java/org/fest/reflect/field/DecoratedInvoker.java
@@ -0,0 +1,146 @@
+/*
+ * Created on Mar 18, 2012
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2006-2009 the original author or authors.
+ */
+package org.fest.reflect.field;
+
+import java.lang.reflect.Proxy;
+
+import org.fest.reflect.field.decorator.DecoratorInvocationHandler;
+import org.fest.reflect.field.decorator.RuntimeExceptionShield;
+
+/**
+ * A decorated invoker allowing to ignore some exceptions or returning decorator result instead of field result.
+ * @author Ivan Hristov
+ */
+public final class DecoratedInvoker<T> {
+
+  private final T target;
+  private final T decorator;
+  private final Invoker<T> invoker;
+  private final Class<?> expectedType;
+  private final DecoratorInvocationHandler<T> decoratorInvocationHandler;
+
+  static <T> DecoratedInvoker<T> newInvoker(T target, T decorator, Class<?> expectedType, Invoker<T> invoker,
+      DecoratorInvocationHandler<T> decoratorInvocationHandler) {
+    return new DecoratedInvoker<T>(target, decorator, expectedType, invoker, decoratorInvocationHandler);
+  }
+
+  private DecoratedInvoker(T target, T decorator, Class<?> expectedType, Invoker<T> invoker,
+      DecoratorInvocationHandler<T> decoratorInvocationHandler) {
+    this.target = target;
+    this.decorator = decorator;
+    this.invoker = invoker;
+    this.expectedType = expectedType;
+    this.decoratorInvocationHandler = decoratorInvocationHandler;
+  }
+
+  /**
+   * Ignores any {@link RuntimeException} which comes from the preceding decorator.
+   * @return the DecoratedResultInvoker ignoring exceptions.
+   */
+  public DecoratedInvoker<T> ignoringDecoratorExceptions() {
+    return ignoringDecoratorExceptionsOfType(RuntimeException.class);
+  }
+
+  /**
+   * Ignores any exception of the {@code exceptionClass} type which comes from the preceding decorator.
+   * @param exceptionClass the exception to ignore - usually a checked exception of decorator method
+   * @return the DecoratedResultInvoker ignoring given exception type.
+   */
+  public DecoratedInvoker<T> ignoringDecoratorExceptionsOfType(Class<?> exceptionClass) {
+    RuntimeExceptionShield runtimeExceptionShield = new RuntimeExceptionShield(decorator, exceptionClass);
+    @SuppressWarnings("unchecked")
+    T exceptionSafeDecorator = (T) Proxy.newProxyInstance(decorator.getClass().getClassLoader(),//
+        new Class[] { expectedType }, runtimeExceptionShield);
+
+    decoratorInvocationHandler.setDecorator(exceptionSafeDecorator);
+
+    return newInvoker(target, exceptionSafeDecorator, expectedType, invoker, decoratorInvocationHandler);
+  }
+
+  /**
+   * Specifies that the result from the decorator should be returned.
+   * <p>
+   * If {@link DecoratedInvoker#ignoringDecoratorExceptions() ignoringDecoratorExceptions()} is used in combination with this
+   * method and an exception is thrown, the default value will be returned (as defined by JLS) for all primitives or null for all
+   * non-primitive.
+   * <p>
+   * Example :<br>
+   * If a {@link RuntimeException} is thrown while executing one of the decorated <code>IExampleService</code> field methods which
+   * returns primitive boolean value, the default value <i>false</i> will be returned.
+   * 
+   * <pre>
+   * field("fieldName").ofType(IExampleService.class).in(target)
+   *                   .postDecorateWith(postDecoratorService)
+   *                   .returningDecoratorResult()
+   *                   .ignoringDecoratorExceptions();
+   * </pre>
+   * In case of several decorators attached to a field, the result from the latest will be returned.
+   * <p>
+   * Example 1:<br>
+   * The result from the <b>pre</b>DecoratorService will be returned
+   * 
+   * <pre>
+   * field("fieldName").ofType(IExampleService.class).in(target)
+   *                   .preDecorateWith(preDecoratorService)
+   *                   .returningDecoratorResult();
+   * </pre>
+   * Example 2:<br>
+   * The result from the <b>post</b>DecoratorService will be returned
+   * 
+   * <pre>
+   * field("fieldName").ofType(IExampleService.class).in(target)
+   *                   .postDecorateWith(postDecoratorService)
+   *                   .returningDecoratorResult();
+   * </pre>
+   * Example 3:<br>
+   * The result from the <b>pre</b>DecoratorService will be returned, since it's the <b>latest</b> attached decorator.
+   * 
+   * <pre>
+   * field("fieldName").ofType(IExampleService.class).in(target)
+   *                   .postDecorateWith(postDecoratorService)
+   *                   .returningDecoratorResult()
+   *                   .<b>pre</b>DecorateWith(preDecoratorService)
+   *                   .returningDecoratorResult();
+   * </pre>
+   */
+  public DecoratedInvoker<T> returningDecoratorResult() {
+    decoratorInvocationHandler.setReturnDecoratorResult(true);
+    return newInvoker(target, decorator, expectedType, invoker, decoratorInvocationHandler);
+  }
+
+  /**
+   * Adds a pre-decorator to an already decorated field.
+   * <p>
+   * Note that if there are more than one pre-decorators assigned to a field they will be executed starting from the last attached
+   * decorator.
+   * @param decorator which methods be called before the same targeted object methods
+   * @return the {@link DecoratedInvoker} pre decorating the target field interface with given decorator.
+   */
+  public DecoratedInvoker<T> preDecorateWith(T decorator) {
+    return invoker.preDecorateWith(decorator);
+  }
+
+  /**
+   * Adds a post-decorator to an already decorated field
+   * <p>
+   * Note that if there are more than one post-decorators assigned to a field they will be executed starting from the first
+   * attached decorator.
+   * @param decorator which methods be called after the same targeted object methods
+   * @return the {@link DecoratedInvoker} post decorating the target field interface with given decorator.
+   */
+  public DecoratedInvoker<T> postDecorateWith(T decorator) {
+    return invoker.postDecorateWith(decorator);
+  }
+}
diff --git a/src/main/java/org/fest/reflect/field/FieldName.java b/src/main/java/org/fest/reflect/field/FieldName.java
new file mode 100644
index 0000000..46e8b01
--- /dev/null
+++ b/src/main/java/org/fest/reflect/field/FieldName.java
@@ -0,0 +1,111 @@
+/*
+ * Created on Aug 17, 2006
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2006-2009 the original author or authors.
+ */
+package org.fest.reflect.field;
+
+import static org.fest.reflect.field.FieldType.newFieldType;
+import static org.fest.reflect.field.FieldTypeRef.newFieldTypeRef;
+import static org.fest.util.Strings.isEmpty;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.fest.reflect.reference.TypeRef;
+
+/**
+ * Understands the name of a field to access using Java Reflection.
+ * <p>
+ * The following is an example of proper usage of this class:
+ * 
+ * <pre>
+ *   // Retrieves the value of the field "name"
+ *   String name = {@link org.fest.reflect.core.Reflection#field(String) field}("name").{@link FieldName#ofType(Class) ofType}(String.class).{@link FieldType#in(Object) in}(person).{@link Invoker#get() get}();
+ *
+ *   // Sets the value of the field "name" to "Yoda"
+ *   {@link org.fest.reflect.core.Reflection#field(String) field}("name").{@link FieldName#ofType(Class) ofType}(String.class).{@link FieldType#in(Object) in}(person).{@link Invoker#set(Object) set}("Yoda");
+ *
+ *   // Retrieves the value of the field "powers"
+ *   List<String> powers = {@link org.fest.reflect.core.Reflection#field(String) field}("powers").{@link #ofType(TypeRef) ofType}(new {@link TypeRef TypeRef}<List<String>>() {}).{@link FieldTypeRef#in(Object) in}(jedi).{@link Invoker#get() get}();
+ *
+ *   // Sets the value of the field "powers"
+ *   List<String> powers = new ArrayList<String>();
+ *   powers.add("heal");
+ *   {@link org.fest.reflect.core.Reflection#field(String) field}("powers").{@link #ofType(TypeRef) ofType}(new {@link TypeRef TypeRef}<List<String>>() {}).{@link FieldTypeRef#in(Object) in}(jedi).{@link Invoker#set(Object) set}(powers);
+ * </pre>
+ * </p>
+ * 
+ * @author Alex Ruiz
+ * @author Ivan Hristov
+ */
+public final class FieldName {
+
+  private final String name;
+  private final List<String> path;
+
+  /**
+   * Creates a new <code>{@link FieldName}</code>: the starting point of the fluent interface for accessing fields using Java
+   * Reflection.
+   * @param name the name of the field to access using Java Reflection.
+   * @return the created <code>FieldName</code>.
+   * @throws NullPointerException if the given name is <code>null</code>.
+   * @throws IllegalArgumentException if the given name is empty.
+   */
+  public static FieldName beginFieldAccess(String name) {
+    validateIsNotNullOrEmpty(name);
+    return new FieldName(name);
+  }
+
+  private static void validateIsNotNullOrEmpty(String name) {
+    if (name == null) throw new NullPointerException("The name of the field to access should not be null");
+    if (isEmpty(name)) throw new IllegalArgumentException("The name of the field to access should not be empty");
+  }
+
+  private FieldName(String name) {
+    this.path = new ArrayList<String>(Arrays.asList(name.split("\\.")));
+    path.remove(path.size() - 1);
+    this.name = name.substring(name.lastIndexOf('.') + 1, name.length());
+  }
+
+  /**
+   * Sets the type of the field to access.
+   * @param <T> the generic type of the field type.
+   * @param type the type of the field to access.
+   * @return a recipient for the field type.
+   * @throws NullPointerException if the given type is <code>null</code>.
+   */
+  public <T> FieldType<T> ofType(Class<T> type) {
+    return newFieldType(name, type, path);
+  }
+
+  /**
+   * Sets the type reference of the field to access. This method reduces casting when the type of the field to access uses
+   * generics.
+   * <p>
+   * For example:
+   * 
+   * <pre>
+   *   List<String> powers = {@link org.fest.reflect.core.Reflection#field(String) field}("powers").{@link #ofType(TypeRef) ofType}(new {@link TypeRef TypeRef}<List<String>>() {}).{@link FieldTypeRef#in(Object) in}(jedi).{@link Invoker#get() get}();
+   * </pre>
+   * </p>
+   * @param <T> the generic type of the field type.
+   * @param type the type of the field to access.
+   * @return a recipient for the field type.
+   * @throws NullPointerException if the given type reference is <code>null</code>.
+   * @since 1.1
+   */
+  public <T> FieldTypeRef<T> ofType(TypeRef<T> type) {
+    return newFieldTypeRef(name, type, path);
+  }
+}
\ No newline at end of file
diff --git a/src/main/java/org/fest/reflect/field/FieldType.java b/src/main/java/org/fest/reflect/field/FieldType.java
new file mode 100644
index 0000000..76e1708
--- /dev/null
+++ b/src/main/java/org/fest/reflect/field/FieldType.java
@@ -0,0 +1,77 @@
+/*
+ * Created on Aug 17, 2006
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2006-2009 the original author or authors.
+ */
+package org.fest.reflect.field;
+
+import static org.fest.reflect.field.Invoker.newInvoker;
+
+import java.util.List;
+
+import org.fest.reflect.exception.ReflectionError;
+
+/**
+ * Understands the type of a field to access using Java Reflection.
+ * <p>
+ * The following is an example of proper usage of this class:
+ * 
+ * <pre>
+ * // Retrieves the value of the field "name"
+ * String name = {@link org.fest.reflect.core.Reflection#field(String) field}("name").{@link FieldName#ofType(Class) ofType}(String.class).{@link FieldType#in(Object) in}(person).{@link Invoker#get() get}();
+ *
+ * // Sets the value of the field "name" to "Yoda"
+ * {@link org.fest.reflect.core.Reflection#field(String) field}("name").{@link FieldName#ofType(Class) ofType}(String.class).{@link FieldType#in(Object) in}(person).{@link Invoker#set(Object) set}("Yoda");
+ * </pre>
+ * </p>
+ * 
+ * @param <T> the generic type of the field.
+ * 
+ * @author Alex Ruiz
+ * @author Ivan Hristov
+ */
+public class FieldType<T> {
+
+  private final List<String> path;
+
+  static <T> FieldType<T> newFieldType(String name, Class<T> type, List<String> path) {
+    if (type == null) throw new NullPointerException("The type of the field to access should not be null");
+    return new FieldType<T>(name, type, path);
+  }
+
+  private final String name;
+  private final Class<T> type;
+
+  private FieldType(String name, Class<T> type, List<String> path) {
+    this.name = name;
+    this.type = type;
+    this.path = path;
+  }
+
+  /**
+   * Returns a new field access invoker, capable of accessing (read/write) the underlying field.
+   * @param target the object containing the field of interest.
+   * @return the created field access invoker.
+   * @throws NullPointerException if the given target is <code>null</code>.
+   * @throws ReflectionError if a field with a matching name and type cannot be found.
+   */
+  public Invoker<T> in(Object target) {
+    Object nestedTarget = null;
+
+    for (String fieldName : path) {
+      nestedTarget = Invoker.getNestedField(fieldName, nestedTarget == null ? target : nestedTarget);
+    }
+
+    return newInvoker(name, type, nestedTarget == null ? target : nestedTarget);
+  }
+
+}
\ No newline at end of file
diff --git a/src/main/java/org/fest/reflect/field/FieldTypeRef.java b/src/main/java/org/fest/reflect/field/FieldTypeRef.java
new file mode 100644
index 0000000..8701502
--- /dev/null
+++ b/src/main/java/org/fest/reflect/field/FieldTypeRef.java
@@ -0,0 +1,80 @@
+/*
+ * Created on Jan 24, 2009
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2009 the original author or authors.
+ */
+package org.fest.reflect.field;
+
+import static org.fest.reflect.field.Invoker.newInvoker;
+
+import java.util.List;
+
+import org.fest.reflect.exception.ReflectionError;
+import org.fest.reflect.reference.TypeRef;
+
+/**
+ * Understands the type of a field to access using Java Reflection. This implementation supports Java generics.
+ * <p>
+ * The following is an example of proper usage of this class:
+ * 
+ * <pre>
+ *   // Retrieves the value of the field "powers"
+ *   List<String> powers = {@link org.fest.reflect.core.Reflection#field(String) field}("powers").{@link FieldName#ofType(TypeRef) ofType}(new {@link TypeRef TypeRef}<List<String>>() {}).{@link #in(Object) in}(jedi).{@link Invoker#get() get}();
+ *
+ *   // Sets the value of the field "powers"
+ *   List<String> powers = new ArrayList<String>();
+ *   powers.add("heal");
+ *   {@link org.fest.reflect.core.Reflection#field(String) field}("powers").{@link FieldName#ofType(TypeRef) ofType}(new {@link TypeRef TypeRef}<List<String>>() {}).{@link #in(Object) in}(jedi).{@link Invoker#set(Object) set}(powers);
+ * </pre>
+ * </p>
+ * 
+ * @param <T> the generic type of the field.
+ * 
+ * @author Alex Ruiz
+ * @author Ivan Hristov
+ * 
+ * @since 1.1
+ */
+public class FieldTypeRef<T> {
+
+  static <T> FieldTypeRef<T> newFieldTypeRef(String name, TypeRef<T> type, List<String> path) {
+    if (type == null) throw new NullPointerException("The type reference of the field to access should not be null");
+    return new FieldTypeRef<T>(name, type, path);
+  }
+
+  private final String name;
+  private final TypeRef<T> type;
+  private final List<String> path;
+
+  private FieldTypeRef(String name, TypeRef<T> type, List<String> path) {
+    this.name = name;
+    this.type = type;
+    this.path = path;
+  }
+
+  /**
+   * Returns a new field invoker. A field invoker is capable of accessing (read/write) the underlying field.
+   * @param target the object containing the field of interest.
+   * @return the created field invoker.
+   * @throws NullPointerException if the given target is <code>null</code>.
+   * @throws ReflectionError if a field with a matching name and type cannot be found.
+   */
+  public Invoker<T> in(Object target) {
+    Object nestedTarget = null;
+
+    for (String fieldName : path) {
+      nestedTarget = Invoker.getNestedField(fieldName, nestedTarget == null ? target : nestedTarget);
+    }
+
+    return newInvoker(name, type, nestedTarget == null ? target : nestedTarget);
+  }
+}
\ No newline at end of file
diff --git a/src/main/java/org/fest/reflect/field/Invoker.java b/src/main/java/org/fest/reflect/field/Invoker.java
new file mode 100644
index 0000000..e7347b5
--- /dev/null
+++ b/src/main/java/org/fest/reflect/field/Invoker.java
@@ -0,0 +1,302 @@
+/*
+ * Created on Oct 31, 2006
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2006-2009 the original author or authors.
+ */
+package org.fest.reflect.field;
+
+import static org.fest.reflect.util.Accessibles.*;
+import static org.fest.util.Arrays.array;
+import static org.fest.util.Strings.*;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Proxy;
+
+import org.fest.reflect.exception.ReflectionError;
+import org.fest.reflect.field.decorator.DecoratorInvocationHandler;
+import org.fest.reflect.field.decorator.PostDecorator;
+import org.fest.reflect.field.decorator.PreDecorator;
+import org.fest.reflect.reference.TypeRef;
+
+/**
+ * Understands the use of reflection to access a field from an object.
+ * <p>
+ * The following is an example of proper usage of this class:
+ * 
+ * <pre>
+ *   // Retrieves the value of the field "name"
+ *   String name = {@link org.fest.reflect.core.Reflection#field(String) field}("name").{@link FieldName#ofType(Class) ofType}(String.class).{@link FieldType#in(Object) in}(person).{@link Invoker#get() get}();
+ * 
+ *   // Sets the value of the field "name" to "Yoda"
+ *   {@link org.fest.reflect.core.Reflection#field(String) field}("name").{@link FieldName#ofType(Class) ofType}(String.class).{@link FieldType#in(Object) in}(person).{@link Invoker#set(Object) set}("Yoda");
+ * 
+ *   // Retrieves the value of the static field "count"
+ *   int count = {@link org.fest.reflect.core.Reflection#staticField(String) staticField}("count").{@link StaticFieldName#ofType(Class) ofType}(int.class).{@link StaticFieldType#in(Class) in}(Person.class).{@link Invoker#get() get}();
+ * 
+ *   // Sets the value of the static field "count" to 3
+ *   {@link org.fest.reflect.core.Reflection#staticField(String) field}("count").{@link StaticFieldName#ofType(Class) ofType}(int.class).{@link StaticFieldType#in(Class) in}(Person.class).{@link Invoker#set(Object) set}(3);
+ * </pre>
+ * 
+ * </p>
+ * 
+ * @param <T> the declared type for the field to access.
+ * 
+ * @author Alex Ruiz
+ * @author Ivan Hristov
+ */
+public final class Invoker<T> {
+
+  private final Object target;
+  private final Field field;
+  private final boolean accessible;
+  private final Class<?> expectedType;
+
+  static <T> Invoker<T> newInvoker(String fieldName, TypeRef<T> expectedType, Object target) {
+    return createInvoker(fieldName, expectedType.rawType(), target);
+  }
+
+  static <T> Invoker<T> newInvoker(String fieldName, Class<T> expectedType, Object target) {
+    return createInvoker(fieldName, expectedType, target);
+  }
+
+  private static <T> Invoker<T> createInvoker(String fieldName, Class<?> expectedType, Object target) {
+    if (target == null) { throw new NullPointerException("Target should not be null"); }
+    Field field = lookupInClassHierarchy(fieldName, typeOf(target));
+    verifyCorrectType(field, expectedType);
+    return new Invoker<T>(target, field, expectedType);
+  }
+
+  private static Class<?> typeOf(Object target) {
+    if (target instanceof Class<?>) return (Class<?>) target;
+    return target.getClass();
+  }
+
+  private static Field lookupInClassHierarchy(String fieldName, Class<?> declaringType) {
+    Field field = null;
+    Class<?> target = declaringType;
+    while (target != null) {
+      field = field(fieldName, target);
+      if (field != null) break;
+      target = target.getSuperclass();
+    }
+    if (field != null) return field;
+    throw new ReflectionError(concat("Unable to find field ", quote(fieldName), " in ", declaringType.getName()));
+  }
+
+  private static void verifyCorrectType(Field field, Class<?> expectedType) {
+    boolean isAccessible = field.isAccessible();
+    try {
+      makeAccessible(field);
+      Class<?> actualType = field.getType();
+      if (!expectedType.isAssignableFrom(actualType)) throw incorrectFieldType(field, actualType, expectedType);
+    } finally {
+      setAccessibleIgnoringExceptions(field, isAccessible);
+    }
+  }
+
+  private Invoker(Object target, Field field, Class<?> expectedType) {
+    this.target = target;
+    this.field = field;
+    this.expectedType = expectedType;
+    accessible = field.isAccessible();
+  }
+
+  private static Field field(String fieldName, Class<?> declaringType) {
+    try {
+      return declaringType.getDeclaredField(fieldName);
+    } catch (NoSuchFieldException e) {
+      return null;
+    }
+  }
+
+  private static ReflectionError incorrectFieldType(Field field, Class<?> actual, Class<?> expected) {
+    String fieldTypeName = field.getDeclaringClass().getName();
+    String message = concat("The type of the field ", quote(field.getName()), " in ", fieldTypeName, " should be <",
+        expected.getName(), "> but was <", actual.getName(), ">");
+    throw new ReflectionError(message);
+  }
+
+  /**
+   * Sets a value in the field managed by this class.
+   * 
+   * @param value the value to set.
+   * @throws ReflectionError if the given value cannot be set.
+   */
+  public void set(T value) {
+    try {
+      setAccessible(field, true);
+      field.set(target, value);
+    } catch (Exception e) {
+      throw new ReflectionError(concat("Unable to update the value in field ", quote(field.getName())), e);
+    } finally {
+      setAccessibleIgnoringExceptions(field, accessible);
+    }
+  }
+
+  /**
+   * <b>Pre</b>-decorates a targeted object's methods.
+   * <p>
+   * Each execution of a targeted object's method will be first performed on the same method of the {@code decorator} object. The
+   * result (if any) from the invocation of the targeted object's method will be returned but you can choose to return the
+   * decorator result if you want to.
+   * <p>
+   * Be aware:
+   * <li>The type of a targeted object should be an interface for this functionality to work</li>
+   * <li>Any exception caused by an invocation of a {@code decorator} object's method will result in disrupting the default
+   * program's flow</li>
+   * <p>
+   * Example: Assuming we have the following code:
+   * 
+   * <pre>
+   * interface IUploadFileService { 
+   *   boolean upload(String file, String destination); 
+   * }
+   * 
+   * public class FileManager {
+   *     
+   *   private IUploadFileService uploadFileService;
+   *   private static final String DEFAULT_DESTINATION = "http://example.org/default/destination/";
+   * 
+   *   public void manage(String fileName) {
+   *     if( uploadFileService.upload(fileName, DEFAULT_DESTINATION) ) {
+   *       System.out.println("File "+fileName+" sent to "+DEFAULT_DESTINATION);
+   *     } else {
+   *       System.out.println("Unable to sent "+fileName+" to "+DEFAULT_DESTINATION);
+   *     } 
+   *   }
+   * }
+   * </pre>
+   * 
+   * Let's say we want to decorate the uploadFileService.upload(...) part, so that additional functionality is executed
+   * <b>before</b> the actual uploadFileService.upload(...) logic, the following code will do the job:
+   * 
+   * <pre>
+   * IUploadFileService uploadFileServiceDecorator = ...; 
+   * FileManager fileManager = new FileManager();
+   * 
+   * field("uploadFileService").ofType(IUploadFileService.class)
+   *                           .in(fileManager)
+   *                           .preDecorateWith(uploadFileServiceDecorator);
+   * </pre>
+   * However, if there is an exception when calling <code>uploadFileServiceDecorator.upload(fileName, DEFAULT_DESTINATION)</code>
+   * the default program's flow will be interrupted and the <code>uploadFileService.upload(fileName, DEFAULT_DESTINATION)</code>
+   * will not be executed.
+   * <p>
+   * @param decorator which methods be called before the same targeted object methods
+   * @return the {@link DecoratedInvoker} pre decorating the target field interface with given decorator.
+   */
+  public DecoratedInvoker<T> preDecorateWith(T decorator) {
+    T target = get();
+    DecoratorInvocationHandler<T> handler = new PreDecorator<T>(target, decorator);
+    @SuppressWarnings("unchecked")
+    T field = (T) Proxy.newProxyInstance(decorator.getClass().getClassLoader(), array(expectedType), handler);
+    set(field);
+    return DecoratedInvoker.newInvoker(target, decorator, expectedType, this, handler);
+  }
+
+  /**
+   * <b>Post</b>-decorates a targeted object's methods.
+   * <p>
+   * After each execution of a targeted object's method, the same method of the {@code decorator} object will be called. The
+   * result (if any) from the invocation of the targeted object's method will be returned but you can choose to return the
+   * decorator result if you want to.
+   * <p>
+   * Be aware:
+   * <li>The type of a targeted object should be an interface for this functionality to work</li>
+   * <li>Any exception caused by an invocation of a {@code decorator} object's method will result in disrupting the default
+   * program's flow</li>
+   * <p>
+   * Example: Assuming we have the following code:
+   * 
+   * <pre>
+   * interface IUploadFileService { 
+   *   boolean upload(String file, String destination); 
+   * }
+   * 
+   * public class FileManager {
+   *     
+   *   private IUploadFileService uploadFileService;
+   *   private static final String DEFAULT_DESTINATION = "http://example.org/default/destination/";
+   * 
+   *   public void manage(String fileName) {
+   *     if( uploadFileService.upload(fileName, DEFAULT_DESTINATION) ) {
+   *       System.out.println("File "+fileName+" sent to "+DEFAULT_DESTINATION);
+   *     } else {
+   *       System.out.println("Unable to sent "+fileName+" to "+DEFAULT_DESTINATION);
+   *     } 
+   *   }
+   * }
+   * </pre>
+   * 
+   * Let's say we want to decorate the uploadFileService.upload(...) part, so that additional functionality is executed
+   * <b>before</b> the actual uploadFileService.upload(...) logic, the following code will do the job:
+   * 
+   * <pre>
+   * IUploadFileService uploadFileServiceDecorator = ...; 
+   * FileManager fileManager = new FileManager();
+   * 
+   * field("uploadFileService").ofType(IUploadFileService.class)
+   *                           .in(fileManager)
+   *                           .postDecorateWith(uploadFileServiceDecorator);
+   * </pre>
+   * However, if there is an exception when calling <code>uploadFileServiceDecorator.upload(fileName, DEFAULT_DESTINATION)</code>
+   * the default program's flow will be interrupted and the <code>uploadFileService.upload(fileName, DEFAULT_DESTINATION)</code>
+   * will not be executed.
+   * <p>
+   * @param decorator which methods be called after the same targeted object methods
+   * @return the {@link DecoratedInvoker} post decorating the target field interface with given decorator.
+   */
+  public DecoratedInvoker<T> postDecorateWith(T decorator) {
+    T target = get();
+    DecoratorInvocationHandler<T> handler = new PostDecorator<T>(target, decorator);
+    @SuppressWarnings("unchecked")
+    T field = (T) Proxy.newProxyInstance(decorator.getClass().getClassLoader(), array(expectedType), handler);
+    set(field);
+    return DecoratedInvoker.newInvoker(target, decorator, expectedType, this, handler);
+  }
+
+  /**
+   * Returns the value of the field managed by this class.
+   * 
+   * @return the value of the field managed by this class.
+   * @throws ReflectionError if the value of the field cannot be retrieved.
+   */
+  public T get() {
+    return Invoker.<T> get(field, accessible, target);
+  }
+
+  static Object getNestedField(String fieldName, Object target) {
+    Field field = lookupInClassHierarchy(fieldName, typeOf(target));
+    return get(field, field.isAccessible(), target);
+  }
+
+  @SuppressWarnings("unchecked")
+  private static <T> T get(Field field, boolean accessible, Object target) {
+    try {
+      setAccessible(field, true);
+      return (T) field.get(target);
+    } catch (Exception e) {
+      throw new ReflectionError(concat("Unable to obtain the value in field " + quote(field.getName())), e);
+    } finally {
+      setAccessibleIgnoringExceptions(field, accessible);
+    }
+  }
+
+  /**
+   * Returns the "real" field managed by this class.
+   * 
+   * @return the "real" field managed by this class.
+   */
+  public Field info() {
+    return field;
+  }
+}
diff --git a/src/main/java/org/fest/reflect/field/StaticFieldName.java b/src/main/java/org/fest/reflect/field/StaticFieldName.java
new file mode 100644
index 0000000..601fc15
--- /dev/null
+++ b/src/main/java/org/fest/reflect/field/StaticFieldName.java
@@ -0,0 +1,102 @@
+/*
+ * Created on Feb 5, 2008
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2006-2009 the original author or authors.
+ */
+package org.fest.reflect.field;
+
+import static org.fest.reflect.field.StaticFieldType.newFieldType;
+import static org.fest.reflect.field.StaticFieldTypeRef.newFieldTypeRef;
+import static org.fest.util.Strings.isEmpty;
+
+import org.fest.reflect.reference.TypeRef;
+
+/**
+ * Understands the name of a static field to access using Java Reflection.
+ * <p>
+ * The following is an example of proper usage of this class:
+ * 
+ * <pre>
+ *   // Retrieves the value of the static field "count"
+ *   int count = {@link org.fest.reflect.core.Reflection#staticField(String) staticField}("count").{@link StaticFieldName#ofType(Class) ofType}(int.class).{@link StaticFieldType#in(Class) in}(Person.class).{@link Invoker#get() get}();
+ *
+ *   // Sets the value of the static field "count" to 3
+ *   {@link org.fest.reflect.core.Reflection#staticField(String) staticField}("count").{@link StaticFieldName#ofType(Class) ofType}(int.class).{@link StaticFieldType#in(Class) in}(Person.class).{@link Invoker#set(Object) set}(3);
+ *
+ *   // Retrieves the value of the static field "commonPowers"
+ *   List<String> commmonPowers = {@link org.fest.reflect.core.Reflection#staticField(String) staticField}("commonPowers").{@link #ofType(TypeRef) ofType}(new {@link TypeRef TypeRef}<List<String>>() {}).{@link StaticFieldTypeRef#in(Class) in}(Jedi.class).{@link Invoker#get() get}();
+ *
+ *   // Sets the value of the static field "commonPowers"
+ *   List<String> commonPowers = new ArrayList<String>();
+ *   commonPowers.add("jump");
+ *   {@link org.fest.reflect.core.Reflection#staticField(String) staticField}("commonPowers").{@link #ofType(TypeRef) ofType}(new {@link TypeRef TypeRef}<List<String>>() {}).{@link StaticFieldTypeRef#in(Class) in}(Jedi.class).{@link Invoker#set(Object) set}(commonPowers);
+ * </pre>
+ * </p>
+ * 
+ * @author Alex Ruiz
+ */
+public final class StaticFieldName {
+
+  /**
+   * Creates a new <code>{@link StaticFieldName}</code>: the starting point of the fluent interface for accessing static fields
+   * using Java Reflection.
+   * @param name the name of the field to access using Java Reflection.
+   * @return the created <code>StaticFieldName</code>.
+   * @throws NullPointerException if the given name is <code>null</code>.
+   * @throws IllegalArgumentException if the given name is empty.
+   */
+  public static StaticFieldName beginStaticFieldAccess(String name) {
+    validateIsNotNullOrEmpty(name);
+    return new StaticFieldName(name);
+  }
+
+  private static void validateIsNotNullOrEmpty(String name) {
+    if (name == null) throw new NullPointerException("The name of the static field to access should not be null");
+    if (isEmpty(name)) throw new IllegalArgumentException("The name of the static field to access should not be empty");
+  }
+
+  private final String name;
+
+  private StaticFieldName(String name) {
+    this.name = name;
+  }
+
+  /**
+   * Sets the type of the field to access.
+   * @param <T> the generic type of the field type.
+   * @param type the type of the field to access.
+   * @return a recipient for the field type.
+   * @throws NullPointerException if the given type is <code>null</code>.
+   */
+  public <T> StaticFieldType<T> ofType(Class<T> type) {
+    return newFieldType(name, type);
+  }
+
+  /**
+   * Sets the type reference of the field to access. This method reduces casting when the type of the field to access uses
+   * generics.
+   * <p>
+   * For example:
+   * 
+   * <pre>
+   *   List<String> commmonPowers = {@link org.fest.reflect.core.Reflection#staticField(String) staticField}("commonPowers").{@link #ofType(TypeRef) ofType}(new {@link TypeRef TypeRef}<List<String>>() {}).{@link StaticFieldTypeRef#in(Class) in}(Jedi.class).{@link Invoker#get() get}();
+   * </pre>
+   * </p>
+   * @param <T> the generic type of the field type.
+   * @param type the type of the field to access.
+   * @return a recipient for the field type.
+   * @throws NullPointerException if the given type reference is <code>null</code>.
+   */
+  public <T> StaticFieldTypeRef<T> ofType(TypeRef<T> type) {
+    return newFieldTypeRef(name, type);
+  }
+}
\ No newline at end of file
diff --git a/src/main/java/org/fest/reflect/field/StaticFieldType.java b/src/main/java/org/fest/reflect/field/StaticFieldType.java
new file mode 100644
index 0000000..a6cc042
--- /dev/null
+++ b/src/main/java/org/fest/reflect/field/StaticFieldType.java
@@ -0,0 +1,64 @@
+/*
+ * Created on Feb 5, 2006
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2006-2009 the original author or authors.
+ */
+package org.fest.reflect.field;
+
+import static org.fest.reflect.field.Invoker.newInvoker;
+
+import org.fest.reflect.exception.ReflectionError;
+
+/**
+ * Understands the type of a static field to access using Java Reflection.
+ * <p>
+ * The following is an example of proper usage of this class:
+ * 
+ * <pre>
+ *   // Retrieves the value of the static field "count"
+ *   int count = {@link org.fest.reflect.core.Reflection#staticField(String) staticField}("count").{@link StaticFieldName#ofType(Class) ofType}(int.class).{@link StaticFieldType#in(Class) in}(Person.class).{@link Invoker#get() get}();
+ *
+ *   // Sets the value of the static field "count" to 3
+ *   {@link org.fest.reflect.core.Reflection#staticField(String) staticField}("count").{@link StaticFieldName#ofType(Class) ofType}(int.class).{@link StaticFieldType#in(Class) in}(Person.class).{@link Invoker#set(Object) set}(3);
+ * </pre>
+ * </p>
+ * 
+ * @param <T> the generic type of the field.
+ * 
+ * @author Alex Ruiz
+ */
+public class StaticFieldType<T> {
+
+  static <T> StaticFieldType<T> newFieldType(String name, Class<T> type) {
+    if (type == null) throw new NullPointerException("The type of the static field to access should not be null");
+    return new StaticFieldType<T>(name, type);
+  }
+
+  private final String name;
+  private final Class<T> type;
+
+  StaticFieldType(String name, Class<T> type) {
+    this.name = name;
+    this.type = type;
+  }
+
+  /**
+   * Returns a new field invoker. A field invoker is capable of accessing (read/write) the underlying field.
+   * @param target the type containing the static field of interest.
+   * @return the created field invoker.
+   * @throws NullPointerException if the given target is <code>null</code>.
+   * @throws ReflectionError if a static field with a matching name and type cannot be found.
+   */
+  public Invoker<T> in(Class<?> target) {
+    return newInvoker(name, type, target);
+  }
+}
\ No newline at end of file
diff --git a/src/main/java/org/fest/reflect/field/StaticFieldTypeRef.java b/src/main/java/org/fest/reflect/field/StaticFieldTypeRef.java
new file mode 100644
index 0000000..93162a1
--- /dev/null
+++ b/src/main/java/org/fest/reflect/field/StaticFieldTypeRef.java
@@ -0,0 +1,69 @@
+/*
+ * Created on Feb 5, 2006
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2006-2009 the original author or authors.
+ */
+package org.fest.reflect.field;
+
+import static org.fest.reflect.field.Invoker.newInvoker;
+
+import org.fest.reflect.exception.ReflectionError;
+import org.fest.reflect.reference.TypeRef;
+
+/**
+ * Understands the type of a static field to access using Java Reflection.
+ * <p>
+ * The following is an example of proper usage of this class:
+ * 
+ * <pre>
+ *   // Retrieves the value of the static field "commonPowers"
+ *   List<String> commmonPowers = {@link org.fest.reflect.core.Reflection#staticField(String) staticField}("commonPowers").{@link StaticFieldName#ofType(TypeRef) ofType}(new {@link TypeRef TypeRef}<List<String>>() {}).{@link StaticFieldTypeRef#in(Class) in}(Jedi.class).{@link Invoker#get() get}();
+ *
+ *   // Sets the value of the static field "commonPowers"
+ *   List<String> commonPowers = new ArrayList<String>();
+ *   commonPowers.add("jump");
+ *   {@link org.fest.reflect.core.Reflection#staticField(String) staticField}("commonPowers").{@link StaticFieldName#ofType(TypeRef) ofType}(new {@link TypeRef TypeRef}<List<String>>() {}).{@link StaticFieldTypeRef#in(Class) in}(Jedi.class).{@link Invoker#set(Object) set}(commonPowers);
+ * </pre>
+ * </p>
+ * 
+ * @param <T> the generic type of the field.
+ * 
+ * @author Alex Ruiz
+ * 
+ * @since 1.1
+ */
+public class StaticFieldTypeRef<T> {
+
+  static <T> StaticFieldTypeRef<T> newFieldTypeRef(String name, TypeRef<T> type) {
+    if (type == null) throw new NullPointerException("The type reference of the static field to access should not be null");
+    return new StaticFieldTypeRef<T>(name, type);
+  }
+
+  private final String name;
+  private final TypeRef<T> type;
+
+  private StaticFieldTypeRef(String name, TypeRef<T> type) {
+    this.name = name;
+    this.type = type;
+  }
+
+  /**
+   * Returns a new field invoker. A field invoker is capable of accessing (read/write) the underlying field.
+   * @param target the type containing the static field of interest.
+   * @return the created field invoker.
+   * @throws NullPointerException if the given target is <code>null</code>.
+   * @throws ReflectionError if a static field with a matching name and type cannot be found.
+   */
+  public Invoker<T> in(Class<?> target) {
+    return newInvoker(name, type, target);
+  }
+}
\ No newline at end of file
diff --git a/src/main/java/org/fest/reflect/field/decorator/DecoratorInvocationHandler.java b/src/main/java/org/fest/reflect/field/decorator/DecoratorInvocationHandler.java
new file mode 100644
index 0000000..56c8d9a
--- /dev/null
+++ b/src/main/java/org/fest/reflect/field/decorator/DecoratorInvocationHandler.java
@@ -0,0 +1,82 @@
+/*
+ * Created on Mar 19, 2012
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2006-2009 the original author or authors.
+ */
+package org.fest.reflect.field.decorator;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * @author Ivan Hristov
+ * 
+ */
+public abstract class DecoratorInvocationHandler<T> implements InvocationHandler {
+
+  private final T target;
+  private T decorator;
+  private boolean returnDecoratorResult = false;
+
+  public DecoratorInvocationHandler(T target, T decorator) {
+    this.target = target;
+    this.decorator = decorator;
+  }
+
+  public void setDecorator(T decorator) {
+    this.decorator = decorator;
+  }
+
+  public T getTarget() {
+    return target;
+  }
+
+  public T getDecorator() {
+    return decorator;
+  }
+
+  public final Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+
+    Object firstResult = null;
+    try {
+      firstResult = invokeFirst(method, args);
+    } catch (InvocationTargetException e) {
+      throw e.getCause();
+    }
+
+    Object secondResult = null;
+    try {
+      secondResult = invokeSecond(method, args);
+    } catch (InvocationTargetException e) {
+      throw e.getCause();
+    }
+
+    return getResult(firstResult, secondResult);
+  }
+
+  protected abstract Object invokeFirst(Method method, Object[] args) throws IllegalArgumentException, IllegalAccessException,
+      InvocationTargetException;
+
+  protected abstract Object invokeSecond(Method method, Object[] args) throws IllegalArgumentException, IllegalAccessException,
+      InvocationTargetException;
+
+  protected abstract Object getResult(Object firstResult, Object secondResult);
+
+  public void setReturnDecoratorResult(boolean returnDecoratorResult) {
+    this.returnDecoratorResult = returnDecoratorResult;
+  }
+
+  protected boolean shouldReturnDecoratorResult() {
+    return returnDecoratorResult;
+  }
+}
diff --git a/src/main/java/org/fest/reflect/field/decorator/PostDecorator.java b/src/main/java/org/fest/reflect/field/decorator/PostDecorator.java
new file mode 100644
index 0000000..2efb336
--- /dev/null
+++ b/src/main/java/org/fest/reflect/field/decorator/PostDecorator.java
@@ -0,0 +1,48 @@
+/*
+ * Created on Mar 19, 2012
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2006-2009 the original author or authors.
+ */
+package org.fest.reflect.field.decorator;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * A proxy for post-decorating a field
+ * @author Ivan Hristov
+ * 
+ */
+public class PostDecorator<T> extends DecoratorInvocationHandler<T> {
+
+  public PostDecorator(T target, T decorator) {
+    super(target, decorator);
+  }
+
+  @Override
+  protected Object invokeFirst(Method method, Object[] args) throws IllegalArgumentException, IllegalAccessException,
+      InvocationTargetException {
+    return method.invoke(getTarget(), args);
+  }
+
+  @Override
+  protected Object invokeSecond(Method method, Object[] args) throws IllegalArgumentException, IllegalAccessException,
+      InvocationTargetException {
+    return method.invoke(getDecorator(), args);
+  }
+
+  @Override
+  protected Object getResult(Object firstResult, Object secondResult) {
+    return shouldReturnDecoratorResult() ? secondResult : firstResult;
+  }
+
+}
diff --git a/src/main/java/org/fest/reflect/field/decorator/PreDecorator.java b/src/main/java/org/fest/reflect/field/decorator/PreDecorator.java
new file mode 100644
index 0000000..447aa61
--- /dev/null
+++ b/src/main/java/org/fest/reflect/field/decorator/PreDecorator.java
@@ -0,0 +1,47 @@
+/*
+ * Created on Mar 19, 2012
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2006-2009 the original author or authors.
+ */
+package org.fest.reflect.field.decorator;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * A proxy for pre-decorating a field
+ * @author Ivan Hristov
+ * 
+ */
+public class PreDecorator<T> extends DecoratorInvocationHandler<T> {
+
+  public PreDecorator(T target, T decorator) {
+    super(target, decorator);
+  }
+
+  @Override
+  protected Object invokeFirst(Method method, Object[] args) throws IllegalArgumentException, IllegalAccessException,
+      InvocationTargetException {
+    return method.invoke(getDecorator(), args);
+  }
+
+  @Override
+  protected Object invokeSecond(Method method, Object[] args) throws IllegalArgumentException, IllegalAccessException,
+      InvocationTargetException {
+    return method.invoke(getTarget(), args);
+  }
+
+  @Override
+  protected Object getResult(Object firstResult, Object secondResult) {
+    return shouldReturnDecoratorResult() ? firstResult : secondResult;
+  }
+}
diff --git a/src/main/java/org/fest/reflect/field/decorator/RuntimeExceptionShield.java b/src/main/java/org/fest/reflect/field/decorator/RuntimeExceptionShield.java
new file mode 100644
index 0000000..84aa12d
--- /dev/null
+++ b/src/main/java/org/fest/reflect/field/decorator/RuntimeExceptionShield.java
@@ -0,0 +1,61 @@
+/*
+ * Created on Mar 19, 2012
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2006-2009 the original author or authors.
+ */
+package org.fest.reflect.field.decorator;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * A proxy for shielding from exception
+ * @author Ivan Hristov
+ * 
+ */
+public class RuntimeExceptionShield implements InvocationHandler {
+
+  private static final Map<Class<?>, Object> DEFAULT_RETURN_VALUES = new HashMap<Class<?>, Object>();
+  private final Object target;
+  private final Class<?> exceptionClass;
+
+  // static init - reference JLS
+  {
+    DEFAULT_RETURN_VALUES.put(byte.class, 0);
+    DEFAULT_RETURN_VALUES.put(short.class, 0);
+    DEFAULT_RETURN_VALUES.put(int.class, 0);
+    DEFAULT_RETURN_VALUES.put(long.class, 0L);
+    DEFAULT_RETURN_VALUES.put(float.class, 0f);
+    DEFAULT_RETURN_VALUES.put(double.class, 0d);
+    DEFAULT_RETURN_VALUES.put(char.class, '\u0000');
+    DEFAULT_RETURN_VALUES.put(boolean.class, false);
+  }
+
+  public RuntimeExceptionShield(Object target, Class<?> exceptionClass) {
+    this.target = target;
+    this.exceptionClass = exceptionClass;
+  }
+
+  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+    try {
+      return method.invoke(target, args);
+    } catch (InvocationTargetException e) {
+      if (!(e.getCause().getClass() == exceptionClass)) throw e.getCause();
+      // shield from specified exceptions
+    }
+    return DEFAULT_RETURN_VALUES.get(method.getReturnType());
+  }
+
+}
diff --git a/src/main/java/org/fest/reflect/field/package.html b/src/main/java/org/fest/reflect/field/package.html
new file mode 100644
index 0000000..a70cf7a
--- /dev/null
+++ b/src/main/java/org/fest/reflect/field/package.html
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<!-- 
+Licensed 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.
+
+Copyright @2007-2009 the original author or authors.
+ -->
+</head>
+<body bgcolor="white">
+<p>
+Provides a "fluent" API 
+for field access via the Java Reflection API.
+</p>
+<p>
+<strong>Note:</strong> Classes in this package are not intended to be used directly. To use them, you need to use the
+class <code>{@link org.fest.reflect.core.Reflection org.fest.reflect.core.Reflection}</code>.
+</p>
+<p>
+Here are some examples:
+<pre>
+   // import static {@link org.fest.reflect.core.Reflection org.fest.reflect.core.Reflection}.*;
+
+   // Retrieves the value of the field "name"
+   String name = {@link org.fest.reflect.core.Reflection#field(String) field}("name").{@link org.fest.reflect.field.FieldName#ofType(Class) ofType}(String.class).{@link org.fest.reflect.field.FieldType#in(Object) in}(person).{@link org.fest.reflect.field.Invoker#get() get}();
+   
+   // Sets the value of the field "name" to "Yoda"
+   {@link org.fest.reflect.core.Reflection#field(String) field}("name").{@link org.fest.reflect.field.FieldName#ofType(Class) ofType}(String.class).{@link org.fest.reflect.field.FieldType#in(Object) in}(person).{@link org.fest.reflect.field.Invoker#set(Object) set}("Yoda");
+
+   // Retrieves the value of the static field "count"
+   int count = {@link org.fest.reflect.core.Reflection#staticField(String) staticField}("count").{@link org.fest.reflect.field.StaticFieldName#ofType(Class) ofType}(int.class).{@link org.fest.reflect.field.StaticFieldType#in(Class) in}(Person.class).{@link org.fest.reflect.field.Invoker#get() get}();
+   
+   // Sets the value of the static field "count" to 3
+   {@link org.fest.reflect.core.Reflection#staticField(String) field}("count").{@link org.fest.reflect.field.StaticFieldName#ofType(Class) ofType}(int.class).{@link org.fest.reflect.field.StaticFieldType#in(Class) in}(Person.class).{@link org.fest.reflect.field.Invoker#set(Object) set}(3);
+</pre>
+</p>
+</body>
+</html>
\ No newline at end of file
diff --git a/src/main/java/org/fest/reflect/innerclass/Invoker.java b/src/main/java/org/fest/reflect/innerclass/Invoker.java
new file mode 100644
index 0000000..7cbbeae
--- /dev/null
+++ b/src/main/java/org/fest/reflect/innerclass/Invoker.java
@@ -0,0 +1,59 @@
+/*
+ * Created on Jan 25, 2009
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2009 the original author or authors.
+ */
+package org.fest.reflect.innerclass;
+
+import static org.fest.util.Strings.concat;
+
+import org.fest.reflect.exception.ReflectionError;
+
+/**
+ * Understands how to obtain a reference to a static inner class.
+ * 
+ * @author Alex Ruiz
+ * 
+ * @since 1.1
+ */
+public class Invoker {
+
+  static Invoker newInvoker(Class<?> declaringClass, String innerClassName) {
+    if (declaringClass == null) throw new NullPointerException("The declaring class should not be null");
+    return new Invoker(declaringClass, innerClassName);
+  }
+
+  private final Class<?> declaringClass;
+  private final String innerClassName;
+
+  private Invoker(Class<?> declaringClass, String innerClassName) {
+    this.declaringClass = declaringClass;
+    this.innerClassName = innerClassName;
+  }
+
+  /**
+   * Returns a reference to the static inner class with the specified name in the specified declaring class.
+   * @return a reference to the static inner class with the specified name in the specified declaring class.
+   * @throws ReflectionError if the static inner class does not exist (since 1.2).
+   */
+  public Class<?> get() {
+    String namespace = declaringClass.getName();
+    for (Class<?> innerClass : declaringClass.getDeclaredClasses())
+      if (innerClass.getName().equals(expectedInnerClassName(namespace))) return innerClass;
+    throw new ReflectionError(concat("The static inner class <", innerClassName, "> cannot be found in ",
+        declaringClass.getName()));
+  }
+
+  private String expectedInnerClassName(String namespace) {
+    return concat(namespace, "$", innerClassName);
+  }
+}
diff --git a/src/main/java/org/fest/reflect/innerclass/StaticInnerClassName.java b/src/main/java/org/fest/reflect/innerclass/StaticInnerClassName.java
new file mode 100644
index 0000000..39670e9
--- /dev/null
+++ b/src/main/java/org/fest/reflect/innerclass/StaticInnerClassName.java
@@ -0,0 +1,81 @@
+/*
+ * Created on Jan 25, 2009
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2009 the original author or authors.
+ */
+package org.fest.reflect.innerclass;
+
+import static org.fest.reflect.innerclass.Invoker.newInvoker;
+import static org.fest.util.Strings.isEmpty;
+
+/**
+ * Understands the name of a static inner class.
+ * <p>
+ * Let's assume we have the class <code>Jedi</code>, which contains two static inner classes: <code>Master</code> and
+ * <code>Padawan</code>.
+ * 
+ * <pre>
+ * public class Jedi {
+ *
+ *   public static class Master {}
+ *
+ *   public static class Padawan {}
+ * }
+ * </pre>
+ * </p>
+ * <p>
+ * The following example shows how to get a reference to the inner class <code>Master</code>:
+ * 
+ * <pre>
+ * Class<?> masterClass = {@link org.fest.reflect.core.Reflection#staticInnerClass(String) staticInnerClass}("Master").{@link org.fest.reflect.innerclass.StaticInnerClassName#in(Class) in}(Jedi.class).{@link org.fest.reflect.innerclass.Invoker#get() get}();
+ * </pre>
+ * </p>
+ * 
+ * @author Alex Ruiz
+ * 
+ * @since 1.1
+ */
+public final class StaticInnerClassName {
+
+  /**
+   * Creates a new </code>{@link StaticInnerClassName}</code>.
+   * @param name the name of the static inner class to obtain.
+   * @return the created <code>StaticInnerClassName</code>.
+   * @throws NullPointerException if the given name is <code>null</code>.
+   * @throws IllegalArgumentException if the given name is empty.
+   */
+  public static StaticInnerClassName startStaticInnerClassAccess(String name) {
+    validateIsNotNullOrEmpty(name);
+    return new StaticInnerClassName(name);
+  }
+
+  private static void validateIsNotNullOrEmpty(String name) {
+    if (name == null) throw new NullPointerException("The name of the static inner class to access should not be null");
+    if (isEmpty(name)) throw new IllegalArgumentException("The name of the static inner class to access should not be empty");
+  }
+
+  private final String name;
+
+  private StaticInnerClassName(String name) {
+    this.name = name;
+  }
+
+  /**
+   * Specifies the declaring class of the static inner class to obtain.
+   * @param declaringClass the declaring class.
+   * @return an object responsible for obtaining a reference to a static inner class.
+   * @throws NullPointerException if the given declaring class is <code>null</code>.
+   */
+  public Invoker in(Class<?> declaringClass) {
+    return newInvoker(declaringClass, name);
+  }
+}
diff --git a/src/main/java/org/fest/reflect/innerclass/package.html b/src/main/java/org/fest/reflect/innerclass/package.html
new file mode 100644
index 0000000..1cb62f1
--- /dev/null
+++ b/src/main/java/org/fest/reflect/innerclass/package.html
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<!-- 
+Licensed 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.
+
+Copyright @2007-2009 the original author or authors.
+ -->
+</head>
+<body bgcolor="white">
+<p>
+Provides a "fluent" API for accessing static inner classes via the Java Reflection API.
+</p>
+<p>
+<strong>Note:</strong> Classes in this package are not intended to be used directly. To use them, you need to use the
+class <code>{@link org.fest.reflect.core.Reflection org.fest.reflect.core.Reflection}</code>.
+</p>
+<p>
+Here are some examples:
+<pre>
+   // import static {@link org.fest.reflect.core.Reflection org.fest.reflect.core.Reflection}.*;
+
+   // Gets the inner class 'Master' in the declaring class 'Jedi':
+   Class<?> masterClass = {@link org.fest.reflect.core.Reflection#staticInnerClass(String) staticInnerClass}("Master").{@link org.fest.reflect.innerclass.StaticInnerClassName#in(Class) in}(Jedi.class).{@link org.fest.reflect.innerclass.Invoker#get() get}();
+</pre>
+</p>
+</body>
+</html>
\ No newline at end of file
diff --git a/src/main/java/org/fest/reflect/method/Invoker.java b/src/main/java/org/fest/reflect/method/Invoker.java
new file mode 100644
index 0000000..0518a3a
--- /dev/null
+++ b/src/main/java/org/fest/reflect/method/Invoker.java
@@ -0,0 +1,134 @@
+/*
+ * Created on Oct 31, 2006
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2006-2009 the original author or authors.
+ */
+package org.fest.reflect.method;
+
+import static org.fest.reflect.util.Accessibles.makeAccessible;
+import static org.fest.reflect.util.Accessibles.setAccessibleIgnoringExceptions;
+import static org.fest.reflect.util.Throwables.targetOf;
+import static org.fest.util.Arrays.format;
+import static org.fest.util.Strings.concat;
+import static org.fest.util.Strings.quote;
+
+import java.lang.reflect.Method;
+
+import org.fest.reflect.exception.ReflectionError;
+
+/**
+ * Understands the use of reflection to access a method from an object.
+ * <p>
+ * 
+ * <pre>
+ *   // Equivalent to call 'person.setName("Luke")'
+ *   {@link org.fest.reflect.core.Reflection#method(String) method}("setName").{@link MethodName#withParameterTypes(Class...) withParameterTypes}(String.class)
+ *                    .{@link MethodParameterTypes#in(Object) in}(person)
+ *                    .{@link Invoker#invoke(Object...) invoke}("Luke");
+ *
+ *   // Equivalent to call 'person.concentrate()'
+ *   {@link org.fest.reflect.core.Reflection#method(String) method}("concentrate").{@link MethodName#in(Object) in}(person).{@link Invoker#invoke(Object...) invoke}();
+ *
+ *   // Equivalent to call 'person.getName()'
+ *   String name = {@link org.fest.reflect.core.Reflection#method(String) method}("getName").{@link MethodName#withReturnType(Class) withReturnType}(String.class)
+ *                                  .{@link MethodReturnType#in(Object) in}(person)
+ *                                  .{@link Invoker#invoke(Object...) invoke}();
+ * </pre>
+ * </p>
+ * 
+ * @param <T> the return type of the method invocation.
+ * 
+ * @author Yvonne Wang
+ */
+public final class Invoker<T> {
+
+  static <T> Invoker<T> newInvoker(String methodName, Object target, Class<?>... parameterTypes) {
+    return createInvoker(methodName, target, parameterTypes);
+  }
+
+  private static <T> Invoker<T> createInvoker(String methodName, Object target, Class<?>... parameterTypes) {
+    if (target == null) throw new NullPointerException("Target should not be null");
+    Method method = lookupInClassHierarchy(methodName, typeOf(target), parameterTypes);
+    return new Invoker<T>(target, method);
+  }
+
+  private static Class<?> typeOf(Object target) {
+    if (target instanceof Class<?>) return (Class<?>) target;
+    return target.getClass();
+  }
+
+  private static Method lookupInClassHierarchy(String methodName, Class<?> targetType, Class<?>[] parameterTypes) {
+    Method method = null;
+    Class<?> type = targetType;
+    while (type != null) {
+      method = method(methodName, type, parameterTypes);
+      if (method != null) break;
+      type = type.getSuperclass();
+    }
+    if (method == null)
+      throw new ReflectionError(concat("Unable to find method ", quote(methodName), " in ", targetType.getName(),
+          " with parameter type(s) ", format(parameterTypes)));
+    return method;
+  }
+
+  private static Method method(String methodName, Class<?> type, Class<?>[] parameterTypes) {
+    try {
+      return type.getDeclaredMethod(methodName, parameterTypes);
+    } catch (SecurityException e) {
+      return null;
+    } catch (NoSuchMethodException e) {
+      return null;
+    }
+  }
+
+  private final Object target;
+  private final Method method;
+
+  private Invoker(Object target, Method method) {
+    this.target = target;
+    this.method = method;
+  }
+
+  /**
+   * Invokes the method managed by this class using the given arguments.
+   * @param args the arguments to use to call the method managed by this class.
+   * @return the result of the method call.
+   * @throws ReflectionError if the method cannot be invoked.
+   */
+  @SuppressWarnings("unchecked")
+  public T invoke(Object... args) {
+    boolean accessible = method.isAccessible();
+    try {
+      makeAccessible(method);
+      return (T) method.invoke(target, args);
+    } catch (Throwable t) {
+      Throwable cause = targetOf(t);
+      if (cause instanceof RuntimeException) throw (RuntimeException) cause;
+      throw cannotInvokeMethod(cause, args);
+    } finally {
+      setAccessibleIgnoringExceptions(method, accessible);
+    }
+  }
+
+  private ReflectionError cannotInvokeMethod(Throwable cause, Object... args) {
+    String message = concat("Unable to invoke method ", quote(method.getName()), " with arguments ", format(args));
+    throw new ReflectionError(message, cause);
+  }
+
+  /**
+   * Returns the "real" method managed by this class.
+   * @return the "real" method managed by this class.
+   */
+  public java.lang.reflect.Method info() {
+    return method;
+  }
+}
diff --git a/src/main/java/org/fest/reflect/method/MethodName.java b/src/main/java/org/fest/reflect/method/MethodName.java
new file mode 100644
index 0000000..97c9054
--- /dev/null
+++ b/src/main/java/org/fest/reflect/method/MethodName.java
@@ -0,0 +1,125 @@
+/*
+ * Created on Aug 17, 2007
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2007-2009 the original author or authors.
+ */
+package org.fest.reflect.method;
+
+import static org.fest.reflect.method.Invoker.newInvoker;
+import static org.fest.reflect.method.MethodParameterTypes.newParameterTypes;
+import static org.fest.reflect.method.MethodReturnType.newReturnType;
+import static org.fest.reflect.method.MethodReturnTypeRef.newReturnTypeRef;
+import static org.fest.util.Strings.isEmpty;
+
+import org.fest.reflect.reference.TypeRef;
+
+/**
+ * Understands the name of a method to invoke using Java Reflection.
+ * <p>
+ * The following is an example of proper usage of this class:
+ * 
+ * <pre>
+ *   // Equivalent to call 'person.setName("Luke")'
+ *   {@link org.fest.reflect.core.Reflection#method(String) method}("setName").{@link MethodName#withParameterTypes(Class...) withParameterTypes}(String.class)
+ *                    .{@link MethodParameterTypes#in(Object) in}(person)
+ *                    .{@link Invoker#invoke(Object...) invoke}("Luke");
+ *
+ *   // Equivalent to call 'person.concentrate()'
+ *   {@link org.fest.reflect.core.Reflection#method(String) method}("concentrate").{@link MethodName#in(Object) in}(person).{@link Invoker#invoke(Object...) invoke}();
+ *
+ *   // Equivalent to call 'person.getName()'
+ *   String name = {@link org.fest.reflect.core.Reflection#method(String) method}("getName").{@link MethodName#withReturnType(Class) withReturnType}(String.class)
+ *                                  .{@link MethodReturnType#in(Object) in}(person)
+ *                                  .{@link Invoker#invoke(Object...) invoke}();
+ *
+ *   // Equivalent to call 'jedi.getPowers()'
+ *   List<String> powers = {@link org.fest.reflect.core.Reflection#method(String) method}("getPowers").{@link MethodName#withReturnType(TypeRef) withReturnType}(new {@link TypeRef TypeRef}<List<String>>() {})
+ *                                            .{@link MethodReturnTypeRef#in(Object) in}(person)
+ *                                            .{@link Invoker#invoke(Object...) invoke}();
+ * </pre>
+ * </p>
+ * 
+ * @author Yvonne Wang
+ * @author Alex Ruiz
+ */
+public final class MethodName {
+
+  /**
+   * Creates a new <code>{@link MethodName}</code>: the starting point of the fluent interface for accessing methods using Java
+   * Reflection.
+   * @param name the name of the method to invoke using Java Reflection.
+   * @return the created <code>MethodName</code>.
+   * @throws NullPointerException if the given name is <code>null</code>.
+   * @throws IllegalArgumentException if the given name is empty.
+   */
+  public static MethodName startMethodAccess(String name) {
+    validateIsNotNullOrEmpty(name);
+    return new MethodName(name);
+  }
+
+  private static void validateIsNotNullOrEmpty(String name) {
+    if (name == null) throw new NullPointerException("The name of the method to access should not be null");
+    if (isEmpty(name)) throw new IllegalArgumentException("The name of the method to access should not be empty");
+  }
+
+  private final String name;
+
+  private MethodName(String name) {
+    this.name = name;
+  }
+
+  /**
+   * Specifies the return type of the method to invoke. This method call is optional if the return type of the method to invoke is
+   * <code>void</code>.
+   * @param <T> the generic type of the method's return type.
+   * @param type the return type of the method to invoke.
+   * @return the created return type holder.
+   * @throws NullPointerException if the given type is <code>null</code>.
+   */
+  public <T> MethodReturnType<T> withReturnType(Class<T> type) {
+    return newReturnType(name, type);
+  }
+
+  /**
+   * Specifies the return type reference of the method to invoke. This method call is optional if the return type of the method to
+   * invoke is <code>void</code>.
+   * @param <T> the generic type of the method's return type.
+   * @param type the return type reference of the method to invoke.
+   * @return the created return type holder.
+   * @throws NullPointerException if the given type reference is <code>null</code>.
+   * @since 1.1
+   */
+  public <T> MethodReturnTypeRef<T> withReturnType(TypeRef<T> type) {
+    return newReturnTypeRef(name, type);
+  }
+
+  /**
+   * Specifies the parameter types of the method to invoke. This method call is optional if the method to invoke does not take
+   * arguments.
+   * @param parameterTypes the parameter types of the method to invoke.
+   * @return the created parameter types holder.
+   * @throws NullPointerException if the array of parameter types is <code>null</code>.
+   */
+  public MethodParameterTypes<Void> withParameterTypes(Class<?>... parameterTypes) {
+    return newParameterTypes(name, parameterTypes);
+  }
+
+  /**
+   * Creates a new invoker for a method that takes no parameters and return value <code>void</code>.
+   * @param target the object containing the method to invoke.
+   * @return the created method invoker.
+   * @throws NullPointerException if the given target is <code>null</code>.
+   */
+  public Invoker<Void> in(Object target) {
+    return newInvoker(name, target);
+  }
+}
\ No newline at end of file
diff --git a/src/main/java/org/fest/reflect/method/MethodParameterTypes.java b/src/main/java/org/fest/reflect/method/MethodParameterTypes.java
new file mode 100644
index 0000000..bf08ed9
--- /dev/null
+++ b/src/main/java/org/fest/reflect/method/MethodParameterTypes.java
@@ -0,0 +1,70 @@
+/*
+ * Created on Aug 17, 2007
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2007-2009 the original author or authors.
+ */
+package org.fest.reflect.method;
+
+import static org.fest.reflect.method.Invoker.newInvoker;
+
+/**
+ * Understands the parameter types of the method to invoke.
+ * <p>
+ * The following is an example of proper usage of this class:
+ * 
+ * <pre>
+ *   // Equivalent to call 'person.setName("Luke")'
+ *   {@link org.fest.reflect.core.Reflection#method(String) method}("setName").{@link MethodName#withParameterTypes(Class...) withParameterTypes}(String.class)
+ *                    .{@link MethodParameterTypes#in(Object) in}(person)
+ *                    .{@link Invoker#invoke(Object...) invoke}("Luke");
+ *
+ *   // Equivalent to call 'person.concentrate()'
+ *   {@link org.fest.reflect.core.Reflection#method(String) method}("concentrate").{@link MethodName#in(Object) in}(person).{@link Invoker#invoke(Object...) invoke}();
+ *
+ *   // Equivalent to call 'person.getName()'
+ *   String name = {@link org.fest.reflect.core.Reflection#method(String) method}("getName").{@link MethodName#withReturnType(Class) withReturnType}(String.class)
+ *                                  .{@link MethodReturnType#in(Object) in}(person)
+ *                                  .{@link Invoker#invoke(Object...) invoke}();
+ * </pre>
+ * </p>
+ * 
+ * @param <T> the generic type of the method's return type.
+ * 
+ * @author Yvonne Wang
+ * @author Alex Ruiz
+ */
+public final class MethodParameterTypes<T> {
+
+  private final String name;
+  private final Class<?>[] parameterTypes;
+
+  static <T> MethodParameterTypes<T> newParameterTypes(String name, Class<?>[] parameterTypes) {
+    if (parameterTypes == null)
+      throw new NullPointerException("The array of parameter types for the method to access should not be null");
+    return new MethodParameterTypes<T>(parameterTypes, name);
+  }
+
+  private MethodParameterTypes(Class<?>[] parameterTypes, String name) {
+    this.name = name;
+    this.parameterTypes = parameterTypes;
+  }
+
+  /**
+   * Creates a new method invoker.
+   * @param target the object containing the method to invoke.
+   * @return the created method invoker.
+   * @throws NullPointerException if the given target is <code>null</code>.
+   */
+  public Invoker<T> in(Object target) {
+    return newInvoker(name, target, parameterTypes);
+  }
+}
\ No newline at end of file
diff --git a/src/main/java/org/fest/reflect/method/MethodReturnType.java b/src/main/java/org/fest/reflect/method/MethodReturnType.java
new file mode 100644
index 0000000..a114ebf
--- /dev/null
+++ b/src/main/java/org/fest/reflect/method/MethodReturnType.java
@@ -0,0 +1,79 @@
+/*
+ * Created on Aug 17, 2007
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2007-2009 the original author or authors.
+ */
+package org.fest.reflect.method;
+
+import static org.fest.reflect.method.Invoker.newInvoker;
+import static org.fest.reflect.method.MethodParameterTypes.newParameterTypes;
+
+/**
+ * Understands the return type of the method to invoke.
+ * <p>
+ * The following is an example of proper usage of this class:
+ * 
+ * <pre>
+ *   // Equivalent to call 'person.setName("Luke")'
+ *   {@link org.fest.reflect.core.Reflection#method(String) method}("setName").{@link MethodName#withParameterTypes(Class...) withParameterTypes}(String.class)
+ *                    .{@link MethodParameterTypes#in(Object) in}(person)
+ *                    .{@link Invoker#invoke(Object...) invoke}("Luke");
+ *
+ *   // Equivalent to call 'person.concentrate()'
+ *   {@link org.fest.reflect.core.Reflection#method(String) method}("concentrate").{@link MethodName#in(Object) in}(person).{@link Invoker#invoke(Object...) invoke}();
+ *
+ *   // Equivalent to call 'person.getName()'
+ *   String name = {@link org.fest.reflect.core.Reflection#method(String) method}("getName").{@link MethodName#withReturnType(Class) withReturnType}(String.class)
+ *                                  .{@link MethodReturnType#in(Object) in}(person)
+ *                                  .{@link Invoker#invoke(Object...) invoke}();
+ * </pre>
+ * </p>
+ * 
+ * @param <T> the generic type of the method's return type.
+ * 
+ * @author Yvonne Wang
+ * @author Alex Ruiz
+ */
+public class MethodReturnType<T> {
+
+  static <T> MethodReturnType<T> newReturnType(String name, Class<T> type) {
+    if (type == null) throw new NullPointerException("The return type of the method to access should not be null");
+    return new MethodReturnType<T>(name);
+  }
+
+  private final String name;
+
+  private MethodReturnType(String name) {
+    this.name = name;
+  }
+
+  /**
+   * Creates a new method invoker.
+   * @param target the object containing the method to invoke.
+   * @return the created method invoker.
+   * @throws NullPointerException if the given target is <code>null</code>.
+   */
+  public Invoker<T> in(Object target) {
+    return newInvoker(name, target);
+  }
+
+  /**
+   * Specifies the parameter types of the method to invoke. This method call is optional if the method to invoke does not take
+   * arguments.
+   * @param parameterTypes the parameter types of the method to invoke.
+   * @return the created parameter types holder.
+   * @throws NullPointerException if the array of parameter types is <code>null</code>.
+   */
+  public MethodParameterTypes<T> withParameterTypes(Class<?>... parameterTypes) {
+    return newParameterTypes(name, parameterTypes);
+  }
+}
\ No newline at end of file
diff --git a/src/main/java/org/fest/reflect/method/MethodReturnTypeRef.java b/src/main/java/org/fest/reflect/method/MethodReturnTypeRef.java
new file mode 100644
index 0000000..c68d012
--- /dev/null
+++ b/src/main/java/org/fest/reflect/method/MethodReturnTypeRef.java
@@ -0,0 +1,74 @@
+/*
+ * Created on Jan 25, 2009
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2009 the original author or authors.
+ */
+package org.fest.reflect.method;
+
+import static org.fest.reflect.method.Invoker.newInvoker;
+import static org.fest.reflect.method.MethodParameterTypes.newParameterTypes;
+
+import org.fest.reflect.reference.TypeRef;
+
+/**
+ * Understands the return type reference of the method to invoke.
+ * <p>
+ * The following is an example of proper usage of this class:
+ * 
+ * <pre>
+ *   // Equivalent to call 'jedi.getPowers()'
+ *   List<String> powers = {@link org.fest.reflect.core.Reflection#method(String) method}("getPowers").{@link MethodName#withReturnType(TypeRef) withReturnType}(new {@link TypeRef TypeRef}<List<String>>() {})
+ *                                            .{@link MethodReturnTypeRef#in(Object) in}(person)
+ *                                            .{@link Invoker#invoke(Object...) invoke}();
+ * </pre>
+ * </p>
+ * 
+ * @param <T> the generic type of the method's return type reference.
+ * 
+ * @author Alex Ruiz
+ * 
+ * @since 1.1
+ */
+public class MethodReturnTypeRef<T> {
+
+  static <T> MethodReturnTypeRef<T> newReturnTypeRef(String name, TypeRef<T> type) {
+    if (type == null) throw new NullPointerException("The return type reference of the method to access should not be null");
+    return new MethodReturnTypeRef<T>(name);
+  }
+
+  private final String name;
+
+  private MethodReturnTypeRef(String name) {
+    this.name = name;
+  }
+
+  /**
+   * Creates a new method invoker.
+   * @param target the object containing the method to invoke.
+   * @return the created method invoker.
+   * @throws NullPointerException if the given target is <code>null</code>.
+   */
+  public Invoker<T> in(Object target) {
+    return newInvoker(name, target);
+  }
+
+  /**
+   * Specifies the parameter types of the method to invoke. This method call is optional if the method to invoke does not take
+   * arguments.
+   * @param parameterTypes the parameter types of the method to invoke.
+   * @return the created parameter types holder.
+   * @throws NullPointerException if the array of parameter types is <code>null</code>.
+   */
+  public MethodParameterTypes<T> withParameterTypes(Class<?>... parameterTypes) {
+    return newParameterTypes(name, parameterTypes);
+  }
+}
\ No newline at end of file
diff --git a/src/main/java/org/fest/reflect/method/StaticMethodName.java b/src/main/java/org/fest/reflect/method/StaticMethodName.java
new file mode 100644
index 0000000..3e07b0b
--- /dev/null
+++ b/src/main/java/org/fest/reflect/method/StaticMethodName.java
@@ -0,0 +1,123 @@
+/*
+ * Created on Feb 20, 2008
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2008-2009 the original author or authors.
+ */
+package org.fest.reflect.method;
+
+import static org.fest.reflect.method.Invoker.newInvoker;
+import static org.fest.reflect.method.StaticMethodParameterTypes.newParameterTypes;
+import static org.fest.reflect.method.StaticMethodReturnType.newReturnType;
+import static org.fest.reflect.method.StaticMethodReturnTypeRef.newReturnTypeRef;
+import static org.fest.util.Strings.isEmpty;
+
+import org.fest.reflect.reference.TypeRef;
+
+/**
+ * Understands the name of a static method to invoke using Java Reflection.
+ * <p>
+ * The following is an example of proper usage of this class:
+ * 
+ * <pre>
+ *   // Equivalent to call 'Jedi.setCommonPower("Jump")'
+ *   {@link org.fest.reflect.core.Reflection#staticMethod(String) staticMethod}("setCommonPower").{@link StaticMethodName#withParameterTypes(Class...) withParameterTypes}(String.class)
+ *                                 .{@link StaticMethodParameterTypes#in(Class) in}(Jedi.class)
+ *                                 .{@link Invoker#invoke(Object...) invoke}("Jump");
+ *
+ *   // Equivalent to call 'Jedi.addPadawan()'
+ *   {@link org.fest.reflect.core.Reflection#staticMethod(String) staticMethod}("addPadawan").{@link StaticMethodName#in(Class) in}(Jedi.class).{@link Invoker#invoke(Object...) invoke}();
+ *
+ *   // Equivalent to call 'Jedi.commonPowerCount()'
+ *   String name = {@link org.fest.reflect.core.Reflection#staticMethod(String) staticMethod}("commonPowerCount").{@link StaticMethodName#withReturnType(Class) withReturnType}(String.class)
+ *                                                 .{@link StaticMethodReturnType#in(Class) in}(Jedi.class)
+ *                                                 .{@link Invoker#invoke(Object...) invoke}();
+ *
+ *   // Equivalent to call 'Jedi.getCommonPowers()'
+ *   List<String> powers = {@link org.fest.reflect.core.Reflection#staticMethod(String) staticMethod}("getCommonPowers").{@link StaticMethodName#withReturnType(TypeRef) withReturnType}(new {@link TypeRef TypeRef}<List<String>>() {})
+ *                                                        .{@link StaticMethodReturnTypeRef#in(Class) in}(Jedi.class)
+ *                                                        .{@link Invoker#invoke(Object...) invoke}();
+ * </pre>
+ * </p>
+ * 
+ * @author Alex Ruiz
+ */
+public final class StaticMethodName {
+
+  /**
+   * Creates a new </code>{@link StaticMethodName}</code>: the starting point of the fluent interface for accessing static methods
+   * using Java Reflection.
+   * @param name the name of the method to access using Java Reflection.
+   * @return the created <code>StaticMethodName</code>.
+   * @throws NullPointerException if the given name is <code>null</code>.
+   * @throws IllegalArgumentException if the given name is empty.
+   */
+  public static StaticMethodName startStaticMethodAccess(String name) {
+    validateIsNotNullOrEmpty(name);
+    return new StaticMethodName(name);
+  }
+
+  private static void validateIsNotNullOrEmpty(String name) {
+    if (name == null) throw new NullPointerException("The name of the static method to access should not be null");
+    if (isEmpty(name)) throw new IllegalArgumentException("The name of the static method to access should not be empty");
+  }
+
+  private final String name;
+
+  private StaticMethodName(String name) {
+    this.name = name;
+  }
+
+  /**
+   * Specifies the return type of the static method to invoke. This method call is optional if the return type of the method to
+   * invoke is <code>void</code>.
+   * @param <T> the generic type of the method's return type.
+   * @param type the return type of the method to invoke.
+   * @return the created return type holder.
+   * @throws NullPointerException if the given type is <code>null</code>.
+   */
+  public <T> StaticMethodReturnType<T> withReturnType(Class<T> type) {
+    return newReturnType(name, type);
+  }
+
+  /**
+   * Specifies the return type reference of the static method to invoke. This method call is optional if the return type of the
+   * method to invoke is <code>void</code>.
+   * @param <T> the generic type of the method's return type.
+   * @param type the return type reference of the method to invoke.
+   * @return the created return type holder.
+   * @throws NullPointerException if the given type reference is <code>null</code>.
+   */
+  public <T> StaticMethodReturnTypeRef<T> withReturnType(TypeRef<T> type) {
+    return newReturnTypeRef(name, type);
+  }
+
+  /**
+   * Specifies the parameter types of the static method to invoke. This method call is optional if the method to invoke does not
+   * take arguments.
+   * @param parameterTypes the parameter types of the method to invoke.
+   * @return the created parameter types holder.
+   * @throws NullPointerException if the array of parameter types is <code>null</code>.
+   */
+  public StaticMethodParameterTypes<Void> withParameterTypes(Class<?>... parameterTypes) {
+    return newParameterTypes(name, parameterTypes);
+  }
+
+  /**
+   * Creates a new invoker for a static method that takes no parameters and return value <code>void</code>.
+   * @param target the object containing the method to invoke.
+   * @return the created method invoker.
+   * @throws NullPointerException if the given target is <code>null</code>.
+   */
+  public Invoker<Void> in(Class<?> target) {
+    return newInvoker(name, target);
+  }
+}
diff --git a/src/main/java/org/fest/reflect/method/StaticMethodParameterTypes.java b/src/main/java/org/fest/reflect/method/StaticMethodParameterTypes.java
new file mode 100644
index 0000000..0354701
--- /dev/null
+++ b/src/main/java/org/fest/reflect/method/StaticMethodParameterTypes.java
@@ -0,0 +1,76 @@
+/*
+ * Created on Aug 17, 2007
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2007-2009 the original author or authors.
+ */
+package org.fest.reflect.method;
+
+import static org.fest.reflect.method.Invoker.newInvoker;
+
+import org.fest.reflect.reference.TypeRef;
+
+/**
+ * Understands the parameter types of the static method to invoke.
+ * <p>
+ * The following is an example of proper usage of this class:
+ * 
+ * <pre>
+ *   // Equivalent to call 'Jedi.setCommonPower("Jump")'
+ *   {@link org.fest.reflect.core.Reflection#staticMethod(String) staticMethod}("setCommonPower").{@link StaticMethodName#withParameterTypes(Class...) withParameterTypes}(String.class)
+ *                                 .{@link StaticMethodParameterTypes#in(Class) in}(Jedi.class)
+ *                                 .{@link Invoker#invoke(Object...) invoke}("Jump");
+ *
+ *   // Equivalent to call 'Jedi.addPadawan()'
+ *   {@link org.fest.reflect.core.Reflection#staticMethod(String) staticMethod}("addPadawan").{@link StaticMethodName#in(Class) in}(Jedi.class).{@link Invoker#invoke(Object...) invoke}();
+ *
+ *   // Equivalent to call 'Jedi.commonPowerCount()'
+ *   String name = {@link org.fest.reflect.core.Reflection#staticMethod(String) staticMethod}("commonPowerCount").{@link StaticMethodName#withReturnType(Class) withReturnType}(String.class)
+ *                                                 .{@link StaticMethodReturnType#in(Class) in}(Jedi.class)
+ *                                                 .{@link Invoker#invoke(Object...) invoke}();
+ *
+ *   // Equivalent to call 'Jedi.getCommonPowers()'
+ *   List<String> powers = {@link org.fest.reflect.core.Reflection#staticMethod(String) staticMethod}("getCommonPowers").{@link StaticMethodName#withReturnType(TypeRef) withReturnType}(new {@link TypeRef TypeRef}<List<String>>() {})
+ *                                                        .{@link StaticMethodReturnTypeRef#in(Class) in}(Jedi.class)
+ *                                                        .{@link Invoker#invoke(Object...) invoke}();
+ * </pre>
+ * </p>
+ * 
+ * @param <T> the generic type of the static method's return type.
+ * 
+ * @author Alex Ruiz
+ */
+public final class StaticMethodParameterTypes<T> {
+
+  static <T> StaticMethodParameterTypes<T> newParameterTypes(String name, Class<?>[] parameterTypes) {
+    if (parameterTypes == null)
+      throw new NullPointerException("The array of parameter types for the static method to access should not be null");
+    return new StaticMethodParameterTypes<T>(name, parameterTypes);
+  }
+
+  private final String name;
+  private final Class<?>[] parameterTypes;
+
+  private StaticMethodParameterTypes(String name, Class<?>[] parameterTypes) {
+    this.name = name;
+    this.parameterTypes = parameterTypes;
+  }
+
+  /**
+   * Creates a new method invoker.
+   * @param target the class containing the static method to invoke.
+   * @return the created method invoker.
+   * @throws NullPointerException if the given target is <code>null</code>.
+   */
+  public Invoker<T> in(Class<?> target) {
+    return newInvoker(name, target, parameterTypes);
+  }
+}
\ No newline at end of file
diff --git a/src/main/java/org/fest/reflect/method/StaticMethodReturnType.java b/src/main/java/org/fest/reflect/method/StaticMethodReturnType.java
new file mode 100644
index 0000000..366843c
--- /dev/null
+++ b/src/main/java/org/fest/reflect/method/StaticMethodReturnType.java
@@ -0,0 +1,85 @@
+/*
+ * Created on Aug 17, 2007
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2007-2009 the original author or authors.
+ */
+package org.fest.reflect.method;
+
+import static org.fest.reflect.method.Invoker.newInvoker;
+import static org.fest.reflect.method.StaticMethodParameterTypes.newParameterTypes;
+
+import org.fest.reflect.reference.TypeRef;
+
+/**
+ * Understands the return type of the static method to invoke.
+ * <p>
+ * The following is an example of proper usage of this class:
+ * 
+ * <pre>
+ *   // Equivalent to call 'Jedi.setCommonPower("Jump")'
+ *   {@link org.fest.reflect.core.Reflection#staticMethod(String) staticMethod}("setCommonPower").{@link StaticMethodName#withParameterTypes(Class...) withParameterTypes}(String.class)
+ *                                 .{@link StaticMethodParameterTypes#in(Class) in}(Jedi.class)
+ *                                 .{@link Invoker#invoke(Object...) invoke}("Jump");
+ *
+ *   // Equivalent to call 'Jedi.addPadawan()'
+ *   {@link org.fest.reflect.core.Reflection#staticMethod(String) staticMethod}("addPadawan").{@link StaticMethodName#in(Class) in}(Jedi.class).{@link Invoker#invoke(Object...) invoke}();
+ *
+ *   // Equivalent to call 'Jedi.commonPowerCount()'
+ *   String name = {@link org.fest.reflect.core.Reflection#staticMethod(String) staticMethod}("commonPowerCount").{@link StaticMethodName#withReturnType(Class) withReturnType}(String.class)
+ *                                                 .{@link StaticMethodReturnType#in(Class) in}(Jedi.class)
+ *                                                 .{@link Invoker#invoke(Object...) invoke}();
+ *
+ *   // Equivalent to call 'Jedi.getCommonPowers()'
+ *   List<String> powers = {@link org.fest.reflect.core.Reflection#staticMethod(String) staticMethod}("getCommonPowers").{@link StaticMethodName#withReturnType(TypeRef) withReturnType}(new {@link TypeRef TypeRef}<List<String>>() {})
+ *                                                        .{@link StaticMethodReturnTypeRef#in(Class) in}(Jedi.class)
+ *                                                        .{@link Invoker#invoke(Object...) invoke}();
+ * </pre>
+ * </p>
+ * 
+ * @param <T> the generic type of the static method's return type.
+ * 
+ * @author Alex Ruiz
+ */
+public class StaticMethodReturnType<T> {
+
+  static <T> StaticMethodReturnType<T> newReturnType(String name, Class<T> type) {
+    if (type == null) throw new NullPointerException("The return type of the static method to access should not be null");
+    return new StaticMethodReturnType<T>(name);
+  }
+
+  private final String name;
+
+  private StaticMethodReturnType(String name) {
+    this.name = name;
+  }
+
+  /**
+   * Creates a new method invoker.
+   * @param target the object containing the method to invoke.
+   * @return the created method invoker.
+   * @throws NullPointerException if the given target is <code>null</code>.
+   */
+  public Invoker<T> in(Class<?> target) {
+    return newInvoker(name, target);
+  }
+
+  /**
+   * Specifies the parameter types of the static method to invoke. This method call is optional if the method to invoke does not
+   * take arguments.
+   * @param parameterTypes the parameter types of the method to invoke.
+   * @return the created parameter types holder.
+   * @throws NullPointerException if the array of parameter types is <code>null</code>.
+   */
+  public StaticMethodParameterTypes<T> withParameterTypes(Class<?>... parameterTypes) {
+    return newParameterTypes(name, parameterTypes);
+  }
+}
\ No newline at end of file
diff --git a/src/main/java/org/fest/reflect/method/StaticMethodReturnTypeRef.java b/src/main/java/org/fest/reflect/method/StaticMethodReturnTypeRef.java
new file mode 100644
index 0000000..6664667
--- /dev/null
+++ b/src/main/java/org/fest/reflect/method/StaticMethodReturnTypeRef.java
@@ -0,0 +1,75 @@
+/*
+ * Created on Jan 25, 2009
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2009 the original author or authors.
+ */
+package org.fest.reflect.method;
+
+import static org.fest.reflect.method.Invoker.newInvoker;
+import static org.fest.reflect.method.StaticMethodParameterTypes.newParameterTypes;
+
+import org.fest.reflect.reference.TypeRef;
+
+/**
+ * Understands the return type of the static method to invoke.
+ * <p>
+ * The following is an example of proper usage of this class:
+ * 
+ * <pre>
+ *   // Equivalent to call 'Jedi.getCommonPowers()'
+ *   List<String> powers = {@link org.fest.reflect.core.Reflection#staticMethod(String) staticMethod}("getCommonPowers").{@link StaticMethodName#withReturnType(TypeRef) withReturnType}(new {@link TypeRef TypeRef}<List<String>>() {})
+ *                                            .{@link StaticMethodReturnTypeRef#in(Class) in}(Jedi.class)
+ *                                            .{@link Invoker#invoke(Object...) invoke}();
+ * </pre>
+ * </p>
+ * 
+ * @param <T> the generic type of the static method's return type.
+ * 
+ * @author Alex Ruiz
+ * 
+ * @since 1.1
+ */
+public class StaticMethodReturnTypeRef<T> {
+
+  static <T> StaticMethodReturnTypeRef<T> newReturnTypeRef(String name, TypeRef<T> type) {
+    if (type == null)
+      throw new NullPointerException("The return type reference of the static method to access should not be null");
+    return new StaticMethodReturnTypeRef<T>(name);
+  }
+
+  private final String name;
+
+  private StaticMethodReturnTypeRef(String name) {
+    this.name = name;
+  }
+
+  /**
+   * Creates a new method invoker.
+   * @param target the object containing the method to invoke.
+   * @return the created method invoker.
+   * @throws NullPointerException if the given target is <code>null</code>.
+   */
+  public Invoker<T> in(Class<?> target) {
+    return newInvoker(name, target);
+  }
+
+  /**
+   * Specifies the parameter types of the static method to invoke. This method call is optional if the method to invoke does not
+   * take arguments.
+   * @param parameterTypes the parameter types of the method to invoke.
+   * @return the created parameter types holder.
+   * @throws NullPointerException if the array of parameter types is <code>null</code>.
+   */
+  public StaticMethodParameterTypes<T> withParameterTypes(Class<?>... parameterTypes) {
+    return newParameterTypes(name, parameterTypes);
+  }
+}
\ No newline at end of file
diff --git a/src/main/java/org/fest/reflect/method/package.html b/src/main/java/org/fest/reflect/method/package.html
new file mode 100644
index 0000000..dc451ea
--- /dev/null
+++ b/src/main/java/org/fest/reflect/method/package.html
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<!-- 
+Licensed 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.
+
+Copyright @2007-2009 the original author or authors.
+ -->
+</head>
+<body bgcolor="white">
+<p>
+Provides a "fluent" API for
+method invocation via the Java Reflection API.
+</p>
+<p>
+<strong>Note:</strong> Classes in this package are not intended to be used directly. To use them, you need to use the
+class <code>{@link org.fest.reflect.core.Reflection org.fest.reflect.core.Reflection}</code>.
+</p>
+<p>
+Here are some examples:
+<pre>
+   // import static {@link org.fest.reflect.core.Reflection org.fest.reflect.core.Reflection}.*;
+
+   // Equivalent to call 'person.setName("Luke")'
+   {@link org.fest.reflect.core.Reflection#method(String) method}("setName").{@link org.fest.reflect.method.MethodName#withParameterTypes(Class...) withParameterTypes}(String.class)
+                    .{@link org.fest.reflect.method.MethodParameterTypes#in(Object) in}(person)
+                    .{@link org.fest.reflect.method.Invoker#invoke(Object...) invoke}("Luke");
+ 
+   // Equivalent to call 'person.concentrate()'
+   {@link org.fest.reflect.core.Reflection#method(String) method}("concentrate").{@link org.fest.reflect.method.MethodName#in(Object) in}(person).{@link org.fest.reflect.method.Invoker#invoke(Object...) invoke}();
+   
+   // Equivalent to call 'person.getName()'
+   String name = {@link org.fest.reflect.core.Reflection#method(String) method}("getName").{@link org.fest.reflect.method.MethodName#withReturnType(Class) withReturnType}(String.class)
+                                  .{@link org.fest.reflect.method.MethodReturnType#in(Object) in}(person)
+                                  .{@link org.fest.reflect.method.Invoker#invoke(Object...) invoke}();   
+
+   // Equivalent to call 'Jedi.class.setCommonPower("Jump")'
+   {@link org.fest.reflect.core.Reflection#staticMethod(String) staticMethod}("setCommonPower").{@link org.fest.reflect.method.StaticMethodName#withParameterTypes(Class...) withParameterTypes}(String.class)
+                                 .{@link org.fest.reflect.method.StaticMethodParameterTypes#in(Class) in}(Jedi.class)
+                                 .{@link org.fest.reflect.method.Invoker#invoke(Object...) invoke}("Jump");
+
+   // Equivalent to call 'Jedi.class.addPadawan()'
+   {@link org.fest.reflect.core.Reflection#staticMethod(String) staticMethod}("addPadawan").{@link org.fest.reflect.method.StaticMethodName#in(Class) in}(Jedi.class).{@link org.fest.reflect.method.Invoker#invoke(Object...) invoke}();
+
+   // Equivalent to call 'Jedi.class.commonPowerCount()'
+   String name = {@link org.fest.reflect.core.Reflection#staticMethod(String) staticMethod}("commonPowerCount").{@link org.fest.reflect.method.StaticMethodName#withReturnType(Class) withReturnType}(String.class)
+                                                 .{@link org.fest.reflect.method.StaticMethodReturnType#in(Class) in}(Jedi.class)
+                                                 .{@link org.fest.reflect.method.Invoker#invoke(Object...) invoke}();
+</pre>
+</p>
+</body>
+</html>
\ No newline at end of file
diff --git a/src/main/java/org/fest/reflect/reference/TypeRef.java b/src/main/java/org/fest/reflect/reference/TypeRef.java
new file mode 100644
index 0000000..f1c75a9
--- /dev/null
+++ b/src/main/java/org/fest/reflect/reference/TypeRef.java
@@ -0,0 +1,54 @@
+/*
+ * Created on Jan 24, 2009
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2009 the original author or authors.
+ */
+package org.fest.reflect.reference;
+
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+
+import org.fest.reflect.exception.ReflectionError;
+
+/**
+ * Understands a references a generic type. Based on Neal Gafter's
+ * <code><a href="http://gafter.blogspot.com/2006/12/super-type-tokens.html" target="_blank">TypeReference</a></code>.
+ * @param <T> the generic type in this reference.
+ * 
+ * @author crazybob at google.com (Bob Lee)
+ * @author Alex Ruiz
+ * 
+ * @since 1.1
+ */
+public abstract class TypeRef<T> {
+
+  private final Class<?> rawType;
+
+  /**
+   * Creates a new </code>{@link TypeRef}</code>.
+   * @throws ReflectionError if the generic type of this reference is missing type parameter.
+   */
+  public TypeRef() {
+    Type superclass = getClass().getGenericSuperclass();
+    if (superclass instanceof Class<?>) throw new ReflectionError("Missing type parameter.");
+    Type type = ((ParameterizedType) superclass).getActualTypeArguments()[0];
+    rawType = type instanceof Class<?> ? (Class<?>) type : (Class<?>) ((ParameterizedType) type).getRawType();
+  }
+
+  /**
+   * Returns the raw type of the generic type in this reference.
+   * @return the raw type of the generic type in this reference.
+   */
+  public final Class<?> rawType() {
+    return rawType;
+  }
+}
diff --git a/src/main/java/org/fest/reflect/reference/package.html b/src/main/java/org/fest/reflect/reference/package.html
new file mode 100644
index 0000000..905a1b2
--- /dev/null
+++ b/src/main/java/org/fest/reflect/reference/package.html
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<!-- 
+Licensed 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.
+
+Copyright @2007-2009 the original author or authors.
+ -->
+</head>
+<body bgcolor="white">
+<p>
+Provides support to use Java Generics overcoming the limitations of erasure. Based on Neal Gafter's
+<a href="http://gafter.blogspot.com/2006/12/super-type-tokens.html" target="_blank">Super Type Tokens</a>.
+</p>
+</body>
+</html>
\ No newline at end of file
diff --git a/src/main/java/org/fest/reflect/type/Type.java b/src/main/java/org/fest/reflect/type/Type.java
new file mode 100644
index 0000000..c7db279
--- /dev/null
+++ b/src/main/java/org/fest/reflect/type/Type.java
@@ -0,0 +1,113 @@
+/*
+ * Created on Jan 23, 2009
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2009 the original author or authors.
+ */
+package org.fest.reflect.type;
+
+import org.fest.reflect.exception.ReflectionError;
+
+import static org.fest.reflect.type.TypeLoader.newLoader;
+import static org.fest.util.Strings.isEmpty;
+
+/**
+ * Understands loading a class dynamically.
+ * <p>
+ * The following is an example of proper usage of this class:
+ * 
+ * <pre>
+ *   // Loads the class 'org.republic.Jedi'
+ *   Class<?> jediType = {@link org.fest.reflect.core.Reflection#type(String) type}("org.republic.Jedi").{@link Type#load() load}();
+ *
+ *   // Loads the class 'org.republic.Jedi' as 'org.republic.Person' (Jedi extends Person)
+ *   Class<Person> jediType = {@link org.fest.reflect.core.Reflection#type(String) type}("org.republic.Jedi").{@link Type#loadAs(Class) loadAs}(Person.class);
+ *
+ *   // Loads the class 'org.republic.Jedi' using a custom class loader
+ *   Class<?> jediType = {@link org.fest.reflect.core.Reflection#type(String) type}("org.republic.Jedi").{@link Type#withClassLoader(ClassLoader) withClassLoader}(myClassLoader).{@link org.fest.reflect.type.TypeLoader#load() load}();
+ * </pre>
+ * </p>
+ * 
+ * @author Alex Ruiz
+ * 
+ * @since 1.1
+ */
+public final class Type {
+
+  /**
+   * Creates a new <code>{@link Type}</code>: the starting point of the fluent interface for loading classes dynamically.
+   * @param name the name of the class to load.
+   * @return the created <code>Type</code>.
+   * @throws NullPointerException if the given name is <code>null</code>.
+   * @throws IllegalArgumentException if the given name is empty.
+   */
+  public static Type newType(String name) {
+    if (name == null) throw new NullPointerException("The name of the class to load should not be null");
+    if (isEmpty(name)) throw new IllegalArgumentException("The name of the class to load should not be empty");
+    return new Type(name);
+  }
+
+  private final String name;
+
+  private Type(String name) {
+    this.name = name;
+  }
+
+  /**
+   * Loads the class with the name specified in this type, using this class' <code>ClassLoader</code>.
+   * @return the loaded class.
+   * @throws ReflectionError wrapping any error that occurred during class loading.
+   */
+  public Class<?> load() {
+    return newLoader(name, thisClassLoader()).load();
+  }
+
+  /**
+   * Loads the class with the name specified in this type, as the given type, using this class' <code>ClassLoader</code>.
+   * <p>
+   * The following example shows how to use this method. Let's assume that we have the class <code>Jedi</code> that extends the
+   * class <code>Person</code>:
+   * 
+   * <pre>
+   * Class<Person> type = {@link org.fest.reflect.core.Reflection#type(String) type}("org.republic.Jedi").{@link Type#loadAs(Class) loadAs}(Person.class);
+   * </pre>
+   * </p>
+   * @param type the given type.
+   * @param <T> the generic type of the type.
+   * @return the loaded class.
+   * @throws NullPointerException if the given type is <code>null</code>.
+   * @throws ReflectionError wrapping any error that occurred during class loading.
+   */
+  public <T> Class<? extends T> loadAs(Class<T> type) {
+    return newLoader(name, thisClassLoader()).loadAs(type);
+  }
+
+  private ClassLoader thisClassLoader() {
+    return getClass().getClassLoader();
+  }
+
+  /**
+   * Specifies the <code>{@link ClassLoader}</code> to use to load the class.
+   * <p>
+   * Example:
+   * 
+   * <pre>
+   * Class<?> type = {@link org.fest.reflect.core.Reflection#type(String) type}("org.republic.Jedi").{@link Type#withClassLoader(ClassLoader) withClassLoader}(myClassLoader).{@link TypeLoader#load() load}();
+   * </pre>
+   * </p>
+   * @param classLoader the given <code>ClassLoader</code>.
+   * @return an object responsible of loading a class with the given <code>ClassLoader</code>.
+   * @throws NullPointerException if the given <code>ClassLoader</code> is <code>null</code>.
+   */
+  public TypeLoader withClassLoader(ClassLoader classLoader) {
+    return newLoader(name, classLoader);
+  }
+}
diff --git a/src/main/java/org/fest/reflect/type/TypeLoader.java b/src/main/java/org/fest/reflect/type/TypeLoader.java
new file mode 100644
index 0000000..c520446
--- /dev/null
+++ b/src/main/java/org/fest/reflect/type/TypeLoader.java
@@ -0,0 +1,99 @@
+/*
+ * Created on Jan 28, 2009
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2009 the original author or authors.
+ */
+package org.fest.reflect.type;
+
+import org.fest.reflect.exception.ReflectionError;
+
+import static org.fest.util.Strings.quote;
+
+/**
+ * Understands loading a class dynamically using a specific <code>{@link ClassLoader}</code>.
+ * 
+ * @author Alex Ruiz
+ * 
+ * @since 1.1
+ */
+public final class TypeLoader {
+
+  static TypeLoader newLoader(String name, ClassLoader classLoader) {
+    if (classLoader == null) throw new NullPointerException("The given class loader should not be null");
+    return new TypeLoader(name, classLoader);
+  }
+
+  private final String name;
+  private final ClassLoader classLoader;
+
+  private TypeLoader(String name, ClassLoader classLoader) {
+    this.name = name;
+    this.classLoader = classLoader;
+  }
+
+  /**
+   * Loads the class with the name specified in this type, using this class' <code>ClassLoader</code>.
+   * <p>
+   * Example:
+   * 
+   * <pre>
+   * Class<?> type = {@link org.fest.reflect.core.Reflection#type(String) type}("org.republic.Jedi").{@link Type#withClassLoader(ClassLoader) withClassLoader}(myClassLoader).{@link TypeLoader#load() load}();
+   * </pre>
+   * </p>
+   * @return the loaded class.
+   * @throws ReflectionError wrapping any error that occurred during class loading.
+   */
+  public Class<?> load() {
+    try {
+      return loadType();
+    } catch (Exception e) {
+      throw new ReflectionError(unableToLoadClassMessage(null), e);
+    }
+  }
+
+  /**
+   * Loads the class with the name specified in this type, as the given type, using this class' <code>ClassLoader</code>.
+   * <p>
+   * The following example shows how to use this method. Let's assume that we have the class <code>Jedi</code> that extends the
+   * class <code>Person</code>:
+   * 
+   * <pre>
+   * Class<Person> type = {@link org.fest.reflect.core.Reflection#type(String) type}("org.republic.Jedi").{@link Type#withClassLoader(ClassLoader) withClassLoader}(myClassLoader).{@link TypeLoader#loadAs(Class) loadAs}(Person.class);
+   * </pre>
+   * </p>
+   * @param type the given type.
+   * @param <T> the generic type of the type.
+   * @return the loaded class.
+   * @throws NullPointerException if the given type is <code>null</code>.
+   * @throws ReflectionError wrapping any error that occurred during class loading.
+   */
+  public <T> Class<? extends T> loadAs(Class<T> type) {
+    if (type == null) throw new NullPointerException("The given type should not be null");
+    try {
+      return loadType().asSubclass(type);
+    } catch (Exception e) {
+      throw new ReflectionError(unableToLoadClassMessage(type), e);
+    }
+  }
+
+  private String unableToLoadClassMessage(Class<?> asType) {
+    StringBuilder msg = new StringBuilder();
+    msg.append("Unable to load class ").append(quote(name));
+    if (asType != null) msg.append(" as ").append(asType.getName());
+    msg.append(" using class loader ").append(classLoader);
+    return msg.toString();
+  }
+
+  private Class<?> loadType() throws ClassNotFoundException {
+    return classLoader.loadClass(name);
+  }
+}
diff --git a/src/main/java/org/fest/reflect/type/package.html b/src/main/java/org/fest/reflect/type/package.html
new file mode 100644
index 0000000..6db260e
--- /dev/null
+++ b/src/main/java/org/fest/reflect/type/package.html
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<!-- 
+Licensed 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.
+
+Copyright @2007-2009 the original author or authors.
+ -->
+</head>
+<body bgcolor="white">
+<p>
+Provides a "fluent" API for loading classes dynamically.
+</p>
+<p>
+<strong>Note:</strong> Classes in this package are not intended to be used directly. To use them, you need to use the
+class <code>{@link org.fest.reflect.core.Reflection org.fest.reflect.core.Reflection}</code>.
+</p>
+<p>
+Here are some examples:
+<pre>
+   // import static {@link org.fest.reflect.core.Reflection org.fest.reflect.core.Reflection}.*;
+
+   // Loads the class 'org.republic.Jedi"
+   Class<?> jediType = {@link org.fest.reflect.core.Reflection#type(String) type}("org.republic.Jedi").{@link org.fest.reflect.type.Type#load() load}();
+</pre>
+</p>
+</body>
+</html>
\ No newline at end of file
diff --git a/src/main/java/org/fest/reflect/util/Accessibles.java b/src/main/java/org/fest/reflect/util/Accessibles.java
new file mode 100644
index 0000000..1935999
--- /dev/null
+++ b/src/main/java/org/fest/reflect/util/Accessibles.java
@@ -0,0 +1,76 @@
+/*
+ * Created on Jan 1, 2008
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2008-2009 the original author or authors.
+ */
+package org.fest.reflect.util;
+
+import java.lang.reflect.AccessibleObject;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ * Understands utility methods related to <code>{@link AccessibleObject}</code>s.
+ * 
+ * @author Alex Ruiz
+ */
+public final class Accessibles {
+
+  /**
+   * Sets the <code>accessible</code> flag of the given <code>{@link AccessibleObject}</code> to the given <code>boolean</code>
+   * value, ignoring any thrown exception.
+   * @param o the given <code>AccessibleObject</code>.
+   * @param accessible the value to set the <code>accessible</code> flag to.
+   */
+  public static void setAccessibleIgnoringExceptions(AccessibleObject o, boolean accessible) {
+    try {
+      setAccessible(o, accessible);
+    } catch (RuntimeException ignored) {}
+  }
+
+  /**
+   * Sets the <code>accessible</code> flag of the given <code>{@link AccessibleObject}</code> to <code>true</code>.
+   * @param o the given <code>AccessibleObject</code>.
+   * @throws SecurityException if the request is denied.
+   */
+  public static void makeAccessible(AccessibleObject o) {
+    setAccessible(o, true);
+  }
+
+  /**
+   * Sets the <code>accessible</code> flag of the given <code>{@link AccessibleObject}</code> to the given <code>boolean</code>
+   * value.
+   * @param o the given <code>AccessibleObject</code>.
+   * @param accessible the value to set the <code>accessible</code> flag to.
+   * @throws SecurityException if the request is denied.
+   */
+  public static void setAccessible(AccessibleObject o, boolean accessible) {
+    AccessController.doPrivileged(new SetAccessibleAction(o, accessible));
+  }
+
+  private static class SetAccessibleAction implements PrivilegedAction<Void> {
+    private final AccessibleObject o;
+    private final boolean accessible;
+
+    SetAccessibleAction(AccessibleObject o, boolean accessible) {
+      this.o = o;
+      this.accessible = accessible;
+    }
+
+    public Void run() {
+      o.setAccessible(accessible);
+      return null;
+    }
+  }
+
+  private Accessibles() {}
+}
diff --git a/src/main/java/org/fest/reflect/util/Throwables.java b/src/main/java/org/fest/reflect/util/Throwables.java
new file mode 100644
index 0000000..83e5132
--- /dev/null
+++ b/src/main/java/org/fest/reflect/util/Throwables.java
@@ -0,0 +1,41 @@
+/*
+ * Created on Mar 19, 2009
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2009 the original author or authors.
+ */
+package org.fest.reflect.util;
+
+import java.lang.reflect.InvocationTargetException;
+
+/**
+ * Understands utility methods related to <code>{@link Throwable}</code>s.
+ * 
+ * @author Alex Ruiz
+ * @since 1.2
+ */
+public final class Throwables {
+
+  /**
+   * Obtains the target of the given <code>{@link Throwable}</code>. If the <code>Throwable</code> is a
+   * <code>{@link InvocationTargetException}</code>, this method will return the "target exception" (not the cause.) For other
+   * <code>Throwable</code>s, the same instance is returned unmodified.
+   * @param t the given <code>Throwable</code>.
+   * @return the target exception, if applicable. Otherwise, this method returns the same <code>Throwable</code> passed as
+   *         argument.
+   */
+  public static Throwable targetOf(Throwable t) {
+    if (t instanceof InvocationTargetException) return ((InvocationTargetException) t).getTargetException();
+    return t;
+  }
+
+  private Throwables() {}
+}
diff --git a/src/main/java/org/fest/reflect/util/package.html b/src/main/java/org/fest/reflect/util/package.html
new file mode 100644
index 0000000..2e3d332
--- /dev/null
+++ b/src/main/java/org/fest/reflect/util/package.html
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<!-- 
+Licensed 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.
+
+Copyright @2007-2009 the original author or authors.
+ -->
+</head>
+<body bgcolor="white">
+<p>
+Utility methods.
+</p>
+</body>
+</html>
\ No newline at end of file
diff --git a/src/main/javadoc/overview.html b/src/main/javadoc/overview.html
new file mode 100644
index 0000000..5e63e4a
--- /dev/null
+++ b/src/main/javadoc/overview.html
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+</head>
+<body>
+<p>
+This document is the API specification for the <a href="http://code.google.com/p/fest/" target="_blank">FEST</a> Reflection 
+Module.
+</p>
+<p>
+In order to use the fluent interface, you need to start with the class 
+<code>{@link org.fest.reflect.core.Reflection org.fest.reflect.core.Reflection}</code>.
+</p>
+</body>
+</html>
\ No newline at end of file
diff --git a/src/site/changes.xml b/src/site/changes.xml
new file mode 100644
index 0000000..f950cf5
--- /dev/null
+++ b/src/site/changes.xml
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document>
+  <properties>
+    <title>Changelog</title>
+    <author email="alex.ruiz.05 at gmail.com">Alex Ruiz</author>
+  </properties>
+  <body>
+    <release version="1.2" date="2009-11-30" description="Subsequent release">
+      <action dev="alexruiz" type="fix" issue="FEST-68" due-to="Francis ANDRE">
+        Method invocation now rethrow the original exception thrown by the method.
+      </action>
+      <action dev="alexruiz" type="fix" issue="FEST-68" due-to="Francis ANDRE">
+        Constructor invocation now rethrow the original exception thrown by the constructor.
+      </action>
+      <action dev="alexruiz" type="add" issue="FEST-235" due-to="Jean-Francois Poilpret">
+        Added static method 'property(String)' to class Reflection. It returns the starting point of the fluent 
+        interface for accessing properties using Bean Instrospection under the hood.
+      </action>
+      <action dev="alexruiz" type="fix" issue="FEST-256">
+        Replaced constructor access in fluent interfaces with static factory methods, resulting in code duplication
+        removal and improved encapsulation.
+      </action>
+      <action dev="alexruiz" type="fix" issue="FEST-257">
+        FEST-Reflect now throws ReflectionError if a static inner class is not found.
+      </action>
+    </release>
+    <release version="1.1" date="2009-02-10" description="Subsequent release">
+      <action dev="alexruiz" type="add" issue="117" due-to="Xavier Dury">
+        Added class org.fest.reflect.type.TypeRef based on Neal Gafter's TypeReference.
+      </action>
+      <action dev="alexruiz" type="add" issue="117" due-to="Xavier Dury">
+        Added support for TypeRef as field type in the fluent interface of the package org.fest.reflect.field.
+      </action>
+      <action dev="alexruiz" type="add" issue="117" due-to="Xavier Dury">
+        Added support for TypeRef as method return type in the fluent interface of the package org.fest.reflect.method.
+      </action>
+      <action dev="alexruiz" type="add" issue="194" due-to="Leo Jay">
+        Added support for accessing static inner classes (code in package org.fest.reflect.innerclass.)
+      </action>
+      <action dev="alexruiz" type="add" issue="278" due-to="Stephen Colebourne">
+        Added support for loading class objects via the method 'type(String)' in org.fest.reflect.core.Reflection and
+        the class(es) in the package org.fest.reflect.type.
+      </action>
+      <action dev="alexruiz" type="fix" issue="287">
+        Renamed class Name to FieldName in package org.fest.reflect.field.
+      </action>
+      <action dev="alexruiz" type="fix" issue="287">
+        Renamed class StaticName to StaticFieldName in package org.fest.reflect.field.
+      </action>
+      <action dev="alexruiz" type="fix" issue="287">
+        Renamed class Type to FieldType in package org.fest.reflect.field.
+      </action>
+      <action dev="alexruiz" type="fix" issue="287">
+        Renamed class StaticType to StaticFieldType in package org.fest.reflect.field.
+      </action>
+      <action dev="alexruiz" type="fix" issue="287">
+        Renamed class Name to MethodName in package org.fest.reflect.method.
+      </action>
+      <action dev="alexruiz" type="fix" issue="287">
+        Renamed class StaticName to StaticMethodName in package org.fest.reflect.method.
+      </action>
+      <action dev="alexruiz" type="fix" issue="287">
+        Renamed class ParameterTypes to MethodParameterTypes in package org.fest.reflect.method.
+      </action>
+      <action dev="alexruiz" type="fix" issue="287">
+        Renamed class StaticParameterTypes to StaticMethodParameterTypes in package org.fest.reflect.method.
+      </action>
+      <action dev="alexruiz" type="fix" issue="287">
+        Renamed class ReturnType to MethodReturnType in package org.fest.reflect.method.
+      </action>
+      <action dev="alexruiz" type="fix" issue="287">
+        Renamed class StaticReturnType to StaticMethodReturnType in package org.fest.reflect.method.
+      </action>
+      <action dev="alexruiz" type="fix" issue="288">
+        All public methods throw NullPointerException if any of their arguments is null.
+      </action>
+    </release>
+    <release version="1.0" date="2009-01-07" description="Subsequent release">
+      <action dev="alexruiz" type="fix">
+        Updated documentation.
+      </action>
+    </release>
+    <release version="0.4" date="2008-02-27" description="Subsequent release">
+      <action dev="alexruiz" type="add" issue="111">
+        Added support for calling static fields and static methods.
+      </action>
+      <action dev="alexruiz" type="fix">
+        Fixed bug in method setAccessible(AccessibleObject, boolean) in org.fest.reflect.util.Accessibles where 'true'
+        was used instead of the specified boolean value.
+      </action>
+    </release>
+    <release version="0.3" date="2008-01-31" description="Subsequent release">
+      <action dev="alexruiz" type="fix" issue="106">
+        Reflection.method now find methods of supertypes.
+      </action>
+    </release>
+    <release version="0.2" date="2008-01-02" description="First public release">
+      <action dev="alexruiz" type="fix">
+        Created class Accessibles to call method 'setAccessible' in an AccessibleObject inside a Privileged Block.
+      </action>
+      <action dev="wanghy" type="fix">
+        Moved class Reflection from package org.fest.reflect to org.fest.reflect.core to remove cyclic dependencies.
+      </action>
+      <action dev="wanghy" type="fix">
+        Moved class ReflectionError from package org.fest.reflect to org.fest.reflect.exception to remove cyclic dependencies.
+      </action>
+    </release>
+  </body>
+</document>
\ No newline at end of file
diff --git a/src/site/resources/images/fest-reflect.png b/src/site/resources/images/fest-reflect.png
new file mode 100644
index 0000000..f37eb8b
Binary files /dev/null and b/src/site/resources/images/fest-reflect.png differ
diff --git a/src/site/site.vm b/src/site/site.vm
new file mode 100644
index 0000000..791d34e
--- /dev/null
+++ b/src/site/site.vm
@@ -0,0 +1,369 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+#macro ( link $href $name )
+  #if ( ( $href.toLowerCase().startsWith("http") || $href.toLowerCase().startsWith("https") ) )
+    <a href="$href" class="externalLink">$name</a>
+  #else
+    <a href="$href">$name</a>
+  #end
+#end
+
+#macro ( banner $banner $id )
+  #if ( $banner )
+    #if( $banner.href )
+      <a href="$banner.href" id="$id">
+    #else
+        <span id="$id">
+    #end
+
+    #if( $banner.src )
+        #set ( $src = $banner.src )
+        #if ( ! ( $src.toLowerCase().startsWith("http") || $src.toLowerCase().startsWith("https") ) )
+            #set ( $src = $PathTool.calculateLink( $src, $relativePath ) )
+            #set ( $src = $src.replaceAll( "\\", "/" ) )
+        #end
+        #if ( $banner.alt )
+            #set ( $alt = $banner.alt )
+        #else
+            #set ( $alt = "" )
+        #end
+        <img src="$src" alt="$alt" />
+    #else
+        $banner.name
+    #end
+
+    #if( $banner.href )
+        </a>
+    #else
+        </span>
+    #end
+  #end
+#end
+
+#macro ( links $links )
+  #set ( $counter = 0 )
+  #foreach( $item in $links )
+    #set ( $counter = $counter + 1 )
+    #set ( $currentItemHref = $PathTool.calculateLink( $item.href, $relativePath ) )
+    #set ( $currentItemHref = $currentItemHref.replaceAll( "\\", "/" ) )
+    #link( $currentItemHref $item.name )
+    #if ( $links.size() > $counter )
+      |
+    #end
+  #end
+#end
+
+#macro ( breadcrumbs $breadcrumbs )
+  #set ( $counter = 0 )
+  #foreach( $item in $breadcrumbs )
+    #set ( $counter = $counter + 1 )
+    #set ( $currentItemHref = $PathTool.calculateLink( $item.href, $relativePath ) )
+    #set ( $currentItemHref = $currentItemHref.replaceAll( "\\", "/" ) )
+
+    #if ( $currentItemHref == $alignedFileName || $currentItemHref == "" )
+      $item.name
+    #else
+      #link( $currentItemHref $item.name )
+    #end
+    #if ( $breadcrumbs.size() > $counter )
+      >
+    #end
+  #end
+#end
+
+#macro ( displayTree $display $item )
+  #if ( $item && $item.items && $item.items.size() > 0 )
+    #foreach( $subitem in $item.items )
+      #set ( $subitemHref = $PathTool.calculateLink( $subitem.href, $relativePath ) )
+      #set ( $subitemHref = $subitemHref.replaceAll( "\\", "/" ) )
+
+      #if ( $alignedFileName == $subitemHref )
+        #set ( $display = true )
+      #end
+
+      #displayTree( $display $subitem )
+    #end
+  #end
+#end
+
+#macro ( menuItem $item )
+  #set ( $collapse = "none" )
+  #set ( $currentItemHref = $PathTool.calculateLink( $item.href, $relativePath ) )
+  #set ( $currentItemHref = $currentItemHref.replaceAll( "\\", "/" ) )
+
+  #if ( $item && $item.items && $item.items.size() > 0 )
+    #if ( $item.collapse == false )
+      #set ( $collapse = "expanded" )
+    #else
+      ## By default collapsed
+      #set ( $collapse = "collapsed" )
+    #end
+
+    #set ( $display = false )
+    #displayTree( $display $item )
+
+    #if ( $alignedFileName == $currentItemHref || $display )
+      #set ( $collapse = "expanded" )
+    #end
+  #end
+  <li class="$collapse">
+    #if ( $item.img )
+      #if ( ! ( $item.img.toLowerCase().startsWith("http") || $item.img.toLowerCase().startsWith("https") ) )
+        #set ( $src = $PathTool.calculateLink( $item.img, $relativePath ) )
+        #set ( $src = $src.replaceAll( "\\", "/" ) )
+        <img src="$src"/>
+      #else
+        <img src="$item.img" align="absbottom" style="border-width: 0"/>
+      #end
+    #end
+    #if ( $alignedFileName == $currentItemHref )
+      <strong>$item.name</strong>
+    #else
+      #link( $currentItemHref $item.name )
+    #end
+  #if ( $item && $item.items && $item.items.size() > 0 )
+    #if ( $collapse == "expanded" )
+      <ul>
+        #foreach( $subitem in $item.items )
+          #menuItem( $subitem )
+        #end
+      </ul>
+    #end
+  #end
+  </li>
+#end
+
+#macro ( mainMenu $menus )
+  #foreach( $menu in $menus )
+    #if ( $menu.name )
+    <h5>$menu.name</h5>
+    #end
+    #if ( $menu.items && $menu.items.size() > 0 )
+    <ul>
+      #foreach( $item in $menu.items )
+        #menuItem( $item )
+      #end
+    </ul>
+    #end
+  #end
+#end
+
+#macro ( copyright )
+  #if ( $project )
+    #set ( $currentYear = ${currentDate.year} + 1900 )
+
+    #if ( ${project.inceptionYear} && ( ${project.inceptionYear} != ${currentYear.toString()} ) )
+      ${project.inceptionYear}-${currentYear}
+    #else
+      ${currentYear}
+    #end
+
+    #if ( ${project.organization} && ${project.organization.name} )
+      ${project.organization.name}
+    #end
+  #end
+#end
+
+#macro ( publishDate $position $publishDate $version )
+  #if ( $publishDate && $publishDate.format )
+    #set ( $format = $publishDate.format )
+  #else
+    #set ( $format = "yyyy-MM-dd" )
+  #end
+
+  $dateFormat.applyPattern( $format )
+
+  #set ( $dateToday = $dateFormat.format( $currentDate ) )
+
+  #if ( $publishDate && $publishDate.position )
+    #set ( $datePosition = $publishDate.position )
+  #else
+    #set ( $datePosition = "left" )
+  #end
+
+  #if ( $version )
+    #if ( $version.position )
+      #set ( $versionPosition = $version.position )
+    #else
+      #set ( $versionPosition = "left" )
+    #end
+  #end
+
+  #set ( $breadcrumbs = $decoration.body.breadcrumbs )
+  #set ( $links = $decoration.body.links )
+
+  #if ( $datePosition.equalsIgnoreCase( "right" ) && $links && $links.size() > 0 )
+    #set ( $prefix = " |" )
+  #else
+    #set ( $prefix = "" )
+  #end
+
+  #if ( $datePosition.equalsIgnoreCase( $position ) )
+    #if ( ( $datePosition.equalsIgnoreCase( "right" ) ) || ( $datePosition.equalsIgnoreCase( "bottom" ) ) )
+      $prefix $i18n.getString( "site-renderer", $locale, "template.lastpublished" ): $dateToday
+      #if ( $versionPosition.equalsIgnoreCase( $position ) )
+         | $i18n.getString( "site-renderer", $locale, "template.version" ): ${project.version}
+      #end
+    #elseif ( ( $datePosition.equalsIgnoreCase( "navigation-bottom" ) ) || ( $datePosition.equalsIgnoreCase( "navigation-top" ) ) )
+      <div id="lastPublished">
+        $i18n.getString( "site-renderer", $locale, "template.lastpublished" ): $dateToday
+        #if ( $versionPosition.equalsIgnoreCase( $position ) )
+           | $i18n.getString( "site-renderer", $locale, "template.version" ): ${project.version}
+        #end
+      </div>
+    #elseif ( $datePosition.equalsIgnoreCase("left") )
+      <div class="xleft">
+        $i18n.getString( "site-renderer", $locale, "template.lastpublished" ): $dateToday
+        #if ( $versionPosition.equalsIgnoreCase( $position ) )
+           | $i18n.getString( "site-renderer", $locale, "template.version" ): ${project.version}
+        #end
+        #if ( $breadcrumbs && $breadcrumbs.size() > 0 )
+          | #breadcrumbs( $breadcrumbs )
+        #end
+      </div>
+    #end
+  #elseif ( $versionPosition.equalsIgnoreCase( $position ) )
+    #if ( ( $versionPosition.equalsIgnoreCase( "right" ) ) || ( $versionPosition.equalsIgnoreCase( "bottom" ) ) )
+      $prefix $i18n.getString( "site-renderer", $locale, "template.version" ): ${project.version}
+    #elseif ( ( $versionPosition.equalsIgnoreCase( "navigation-bottom" ) ) || ( $versionPosition.equalsIgnoreCase( "navigation-top" ) ) )
+      <div id="lastPublished">
+        $i18n.getString( "site-renderer", $locale, "template.version" ): ${project.version}
+      </div>
+    #elseif ( $versionPosition.equalsIgnoreCase("left") )
+      <div class="xleft">
+        $i18n.getString( "site-renderer", $locale, "template.version" ): ${project.version}
+        #if ( $breadcrumbs && $breadcrumbs.size() > 0 )
+          | #breadcrumbs( $breadcrumbs )
+        #end
+      </div>
+    #end
+  #elseif ( $position.equalsIgnoreCase( "left" ) )
+    #if ( $breadcrumbs && $breadcrumbs.size() > 0 )
+      <div class="xleft">
+        #breadcrumbs( $breadcrumbs )
+      </div>
+    #end
+  #end
+#end
+
+#macro ( poweredByLogo $poweredBy )
+    #if( $poweredBy )
+        #foreach ($item in $poweredBy)
+            #if( $item.href )
+                #set ( $href = $PathTool.calculateLink( $item.href, $relativePath ) )
+                #set ( $href = $href.replaceAll( "\\", "/" ) )
+            #else
+                #set ( $href="http://maven.apache.org/" )
+            #end
+
+            #if( $item.name )
+                #set ( $name = $item.name )
+            #else
+                #set ( $name = $i18n.getString( "site-renderer", $locale, "template.builtby" )  )
+                #set ( $name = "${name} Maven"  )
+            #end
+
+            #if( $item.img )
+                #set ( $img = $item.img )
+            #else
+                #set ( $img = "images/logos/maven-feather.png" )
+            #end
+
+            <a href="$href" title="$name" class="poweredBy">
+              #set ( $img = $PathTool.calculateLink( $img, $relativePath ) )
+              #set ( $img = $img.replaceAll( "\\", "/" ) )
+              <img alt="$name" src="$img" />
+            </a>
+        #end
+        #if( $poweredBy.isEmpty() )
+          <a href="http://maven.apache.org/" title="$i18n.getString( "site-renderer", $locale, "template.builtby" ) Maven" class="poweredBy">
+            <img alt="$i18n.getString( "site-renderer", $locale, "template.builtby" ) Maven" src="$relativePath/images/logos/maven-feather.png"></img>
+          </a>
+        #end
+    #else
+        <a href="http://maven.apache.org/" title="$i18n.getString( "site-renderer", $locale, "template.builtby" ) Maven" class="poweredBy">
+          <img alt="$i18n.getString( "site-renderer", $locale, "template.builtby" ) Maven" src="$relativePath/images/logos/maven-feather.png"></img>
+        </a>
+    #end
+#end
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <title>$title</title>
+    <style type="text/css" media="all">
+      @import url("$relativePath/css/maven-base.css");
+      @import url("$relativePath/css/maven-theme.css");
+      @import url("$relativePath/css/site.css");
+    </style>
+    <link rel="stylesheet" href="$relativePath/css/print.css" type="text/css" media="print" />
+    #foreach( $author in $authors )
+      <meta name="author" content="$author" />
+    #end
+    <meta http-equiv="Content-Type" content="text/html; charset=${outputEncoding}" />
+    #if ( $decoration.body.head )
+      #foreach( $item in $decoration.body.head.getChildren() )
+        ## Workaround for DOXIA-150 due to a non-desired behaviour in p-u
+        ## @see org.codehaus.plexus.util.xml.Xpp3Dom#toString()
+        ## @see org.codehaus.plexus.util.xml.Xpp3Dom#toUnescapedString()
+        #set ( $documentHeader = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" )
+        #set ( $documentHeader = $documentHeader.replaceAll( "\\", "" ) )
+        #if ( $item.name == "script" )
+          $StringUtils.replace( $item.toUnescapedString(), $documentHeader, "" )
+        #else
+          $StringUtils.replace( $item.toString(), $documentHeader, "" )
+        #end
+      #end
+    #end
+  </head>
+  <body class="composite">
+    <div id="banner">
+      #banner( $decoration.bannerLeft "bannerLeft" )
+      #banner( $decoration.bannerRight "bannerRight" )
+      <span id="bannerRight">
+      </span>
+      <div class="clear">
+        <hr/>
+      </div>
+    </div>
+    <div id="breadcrumbs">
+      #publishDate( "left" $decoration.publishDate $decoration.version )
+      <div class="xright">
+        <a href="http://code.google.com/p/fest" target="_blank">FEST @ Google Code</a>
+      </div>
+      <div class="clear">
+        <hr/>
+      </div>
+    </div>
+    <div id="leftColumn">
+      <div id="navcolumn">
+       #publishDate( "navigation-top" $decoration.publishDate $decoration.version )
+       #mainMenu( $decoration.body.menus )
+        <a href="http://maven.apache.org" target="_blank" title="Build with Maven 2" class="poweredBy">
+          <img alt="Build with Maven 2" src="./images/maven.png">
+        </a>
+        <p></p>
+       #publishDate( "navigation-bottom" $decoration.publishDate $decoration.version )
+      </div>
+    </div>
+    <div id="bodyColumn">
+      <div id="contentBox">
+        $bodyContent
+      </div>
+    </div>
+    <div class="clear">
+      <hr/>
+    </div>
+    <div id="footer">
+      <div class="xright">©#copyright()#publishDate( "bottom" $decoration.publishDate $decoration.version )</div>
+      <div class="clear">
+        <hr/>
+      </div>
+    </div>
+<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+_uacct = "UA-847284-6";
+urchinTracker();
+</script>
+  </body>
+</html>
diff --git a/src/site/site.xml b/src/site/site.xml
new file mode 100644
index 0000000..89e12d2
--- /dev/null
+++ b/src/site/site.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<project name="FEST-Reflect">
+	<skin>
+		<groupId>org.easytesting</groupId>
+		<artifactId>fest-site-skin</artifactId>
+		<version>1.0</version>
+	</skin>
+	<bannerLeft>
+		<name>FEST-Reflect</name>
+		<src>/images/fest-reflect.png</src>
+		<href>index.php</href>
+	</bannerLeft>
+  <poweredBy>
+    <logo name="Built with Maven 2" href="http://maven.apache.org"
+      img="images/logos/maven-feather.png" />
+  </poweredBy>
+
+	<body>
+		<breadcrumbs>
+			<item name="FEST" href="../index.php" />
+      <item name="Reflection" href="index.php"/>
+    </breadcrumbs>
+		<menu ref="reports"/>		
+	</body>
+</project>
diff --git a/src/site/xdoc/index.xml b/src/site/xdoc/index.xml
new file mode 100644
index 0000000..00ef862
--- /dev/null
+++ b/src/site/xdoc/index.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document>
+
+	<properties>
+		<title>Welcome</title>
+    <!--meta HTTP-EQUIV="REFRESH" content="0; url=http://fest.easytesting.org/reflect/index.php" /-->
+	</properties>
+
+  <body>
+    <p>
+    You are being redirected to the <a href="index.php">wiki page</a>.
+    </p>
+  </body>
+</document>
\ No newline at end of file
diff --git a/src/test/java/org/fest/reflect/Jedi.java b/src/test/java/org/fest/reflect/Jedi.java
new file mode 100644
index 0000000..4ca14e2
--- /dev/null
+++ b/src/test/java/org/fest/reflect/Jedi.java
@@ -0,0 +1,114 @@
+/*
+ * Created on May 18, 2007
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2007-2009 the original author or authors.
+ */
+package org.fest.reflect;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Understands a Jedi.
+ * 
+ * @author Alex Ruiz
+ */
+public class Jedi extends Person {
+
+  private static List<String> commonPowers = new ArrayList<String>();
+
+  private final List<String> powers = new ArrayList<String>();
+  private boolean master;
+
+  public Jedi(String name) {
+    super(name);
+  }
+
+  public void addPower(String power) {
+    powers.add(power);
+  }
+
+  public String powerAt(int index) {
+    return powers.get(index);
+  }
+
+  public int powerCount() {
+    return powers.size();
+  }
+
+  public void clearPowers() {
+    powers.clear();
+  }
+
+  public void makeMaster() {
+    master = true;
+  }
+
+  public List<String> powers() {
+    return getPowers();
+  }
+
+  public List<String> getPowers() {
+    return new ArrayList<String>(powers);
+  }
+
+  public void setPowers(List<String> newPowers) {
+    powers.clear();
+    powers.addAll(newPowers);
+  }
+
+  public List<String> powersThatStartWith(String prefix) {
+    List<String> sub = new ArrayList<String>();
+    for (String power : powers)
+      if (power != null && power.startsWith(prefix)) sub.add(power);
+    return sub;
+  }
+
+  public boolean isMaster() {
+    return master;
+  }
+
+  public void throwRuntimeException() {
+    throw new IllegalStateException("Somehow I got in an illegal state");
+  }
+
+  public void throwCheckedException() throws Exception {
+    throw new Exception("I don't know what's wrong");
+  }
+
+  public static void addCommonPower(String power) {
+    commonPowers.add(power);
+  }
+
+  public static String commonPowerAt(int index) {
+    return commonPowers.get(index);
+  }
+
+  public static int commonPowerCount() {
+    return commonPowers.size();
+  }
+
+  public static void clearCommonPowers() {
+    commonPowers.clear();
+  }
+
+  public static List<String> commonPowers() {
+    return new ArrayList<String>(commonPowers);
+  }
+
+  public static List<String> commonPowersThatStartWith(String prefix) {
+    List<String> sub = new ArrayList<String>();
+    for (String power : commonPowers)
+      if (power != null && power.startsWith(prefix)) sub.add(power);
+    return sub;
+  }
+}
\ No newline at end of file
diff --git a/src/test/java/org/fest/reflect/Person.java b/src/test/java/org/fest/reflect/Person.java
new file mode 100644
index 0000000..58bdcc2
--- /dev/null
+++ b/src/test/java/org/fest/reflect/Person.java
@@ -0,0 +1,57 @@
+/*
+ * Created on May 17, 2007
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2007-2009 the original author or authors.
+ */
+package org.fest.reflect;
+
+/**
+ * Understands a person.
+ * 
+ * @author Yvonne Wang
+ */
+public class Person {
+
+  private static int count;
+
+  private String name;
+
+  public Person() {}
+
+  public Person(String name) {
+    setName(name);
+  }
+
+  public Person(int name) {
+    throw new IllegalArgumentException("The name of a person cannot be a number");
+  }
+
+  public Person(Person person) throws Exception {
+    throw new Exception("A person cannot be created from another person");
+  }
+
+  public String getName() {
+    return name;
+  }
+
+  public void setName(String name) {
+    this.name = name;
+  }
+
+  public static int getCount() {
+    return count;
+  }
+
+  public static void setCount(int count) {
+    Person.count = count;
+  }
+}
diff --git a/src/test/java/org/fest/reflect/beanproperty/Property_Test.java b/src/test/java/org/fest/reflect/beanproperty/Property_Test.java
new file mode 100644
index 0000000..cf8214a
--- /dev/null
+++ b/src/test/java/org/fest/reflect/beanproperty/Property_Test.java
@@ -0,0 +1,165 @@
+/*
+ * Created on Nov 23, 2009
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2009 the original author or authors.
+ */
+package org.fest.reflect.beanproperty;
+
+import static org.fest.reflect.util.ExpectedFailures.expectIllegalArgumentException;
+import static org.fest.reflect.util.ExpectedFailures.expectNullPointerException;
+import static org.fest.reflect.util.ExpectedFailures.expectReflectionError;
+import static org.fest.util.Lists.newArrayList;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.beans.PropertyDescriptor;
+import java.util.List;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import org.fest.reflect.Jedi;
+import org.fest.reflect.Person;
+import org.fest.reflect.reference.TypeRef;
+import org.fest.test.CodeToTest;
+
+/**
+ * Tests for the fluent interface for accessing properties.
+ * 
+ * @author Alex Ruiz
+ */
+public class Property_Test {
+
+  private Person person;
+
+  @Before
+  public void setUp() {
+    person = new Person("Luke");
+  }
+
+  @Test
+  public void should_throw_error_if_property_name_is_null() {
+    expectNullPointerException("The name of the property to access should not be null").on(new CodeToTest() {
+      public void run() {
+        PropertyName.startPropertyAccess(null);
+      }
+    });
+  }
+
+  @Test
+  public void should_throw_error_if_property_name_is_empty() {
+    expectIllegalArgumentException("The name of the property to access should not be empty").on(new CodeToTest() {
+      public void run() {
+        PropertyName.startPropertyAccess("");
+      }
+    });
+  }
+
+  @Test
+  public void should_throw_error_if_property_type_is_null() {
+    expectNullPointerException("The type of the property to access should not be null").on(new CodeToTest() {
+      public void run() {
+        PropertyName.startPropertyAccess("name").ofType((Class<?>) null);
+      }
+    });
+  }
+
+  @Test
+  public void should_throw_error_if_target_is_null() {
+    expectNullPointerException("Target should not be null").on(new CodeToTest() {
+      public void run() {
+        PropertyName.startPropertyAccess("name").ofType(String.class).in(null);
+      }
+    });
+  }
+
+  @Test
+  public void should_get_property_value() {
+    String personName = PropertyName.startPropertyAccess("name").ofType(String.class).in(person).get();
+    assertEquals("Luke", personName);
+  }
+
+  @Test
+  public void should_get_property_value_defined_in_object_class() {
+    Class<?> personClass = PropertyName.startPropertyAccess("class").ofType(Class.class).in(person).get();
+    assertEquals(Person.class, personClass);
+  }
+
+  @Test
+  public void should_set_property_value() {
+    PropertyName.startPropertyAccess("name").ofType(String.class).in(person).set("Leia");
+    assertEquals("Leia", person.getName());
+  }
+
+  @Test
+  public void should_return_real_property() {
+    PropertyDescriptor property = PropertyName.startPropertyAccess("name").ofType(String.class).in(person).info();
+    assertNotNull(property);
+    assertEquals("name", property.getName());
+    assertEquals(String.class, property.getPropertyType());
+  }
+
+  @Test
+  public void should_throw_error_if_wrong_property_type_was_specified() {
+    String message = "The type of the property 'name' in org.fest.reflect.Person should be <java.lang.Integer> but was <java.lang.String>";
+    expectReflectionError(message).on(new CodeToTest() {
+      public void run() {
+        PropertyName.startPropertyAccess("name").ofType(Integer.class).in(person).get();
+      }
+    });
+  }
+
+  @Test
+  public void should_throw_error_if_property_name_is_invalid() {
+    expectReflectionError("Unable to find property 'age' in org.fest.reflect.Person").on(new CodeToTest() {
+      public void run() {
+        PropertyName.startPropertyAccess("age").ofType(Integer.class).in(person);
+      }
+    });
+  }
+
+  @Test
+  public void should_get_property_in_super_type() {
+    Jedi jedi = new Jedi("Yoda");
+    String jediName = PropertyName.startPropertyAccess("name").ofType(String.class).in(jedi).get();
+    assertEquals("Yoda", jediName);
+  }
+
+  @Test
+  public void should_throw_error_if_TypeRef_is_null() {
+    expectNullPointerException("The type reference of the property to access should not be null").on(new CodeToTest() {
+      public void run() {
+        PropertyName.startPropertyAccess("name").ofType((TypeRef<?>) null);
+      }
+    });
+  }
+
+  @Test
+  public void should_use_TypeRef_to_read_property() {
+    Jedi jedi = new Jedi("Yoda");
+    jedi.addPower("heal");
+    List<String> powers = PropertyName.startPropertyAccess("powers").ofType(new TypeRef<List<String>>() {}).in(jedi).get();
+    assertEquals(1, powers.size());
+    assertEquals("heal", powers.get(0));
+
+  }
+
+  @Test
+  public void should_use_TypeRef_to_write_property() {
+    Jedi jedi = new Jedi("Yoda");
+    List<String> powers = newArrayList("heal");
+    PropertyName.startPropertyAccess("powers").ofType(new TypeRef<List<String>>() {}).in(jedi).set(powers);
+    assertEquals(1, jedi.powers().size());
+    assertEquals("heal", jedi.powers().get(0));
+  }
+}
diff --git a/src/test/java/org/fest/reflect/constructor/Constructor_Test.java b/src/test/java/org/fest/reflect/constructor/Constructor_Test.java
new file mode 100644
index 0000000..b909e74
--- /dev/null
+++ b/src/test/java/org/fest/reflect/constructor/Constructor_Test.java
@@ -0,0 +1,107 @@
+/*
+ * Created on May 17, 2007
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2007-2009 the original author or authors.
+ */
+package org.fest.reflect.constructor;
+
+import static org.fest.reflect.util.ExpectedFailures.expectIllegalArgumentException;
+import static org.fest.reflect.util.ExpectedFailures.expectNullPointerException;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.lang.reflect.Constructor;
+
+import org.junit.Test;
+
+import org.fest.reflect.Person;
+import org.fest.reflect.exception.ReflectionError;
+import org.fest.test.CodeToTest;
+
+/**
+ * Tests for the fluent interface for constructors.
+ * 
+ * @author Alex Ruiz
+ * @author Yvonne Wang
+ */
+public class Constructor_Test {
+
+  @Test
+  public void should_create_new_instance_with_default_constructor() {
+    Person person = TargetType.startConstructorAccess().in(Person.class).newInstance();
+    assertNotNull(person);
+    assertNull(person.getName());
+  }
+
+  @Test
+  public void should_create_new_instance_using_given_constructor_parameters() {
+    Person person = TargetType.startConstructorAccess().withParameterTypes(String.class).in(Person.class).newInstance("Yoda");
+    assertNotNull(person);
+    assertEquals("Yoda", person.getName());
+  }
+
+  @Test
+  public void should_return_real_constructor() {
+    Constructor<Person> constructor = TargetType.startConstructorAccess().withParameterTypes(String.class).in(Person.class)
+        .info();
+    assertNotNull(constructor);
+    Class<?>[] parameterTypes = constructor.getParameterTypes();
+    assertEquals(1, parameterTypes.length);
+    assertEquals(String.class, parameterTypes[0]);
+  }
+
+  @Test
+  public void should_throw_error_if_parameter_type_array_is_null() {
+    expectNullPointerException("The array of parameter types should not be null").on(new CodeToTest() {
+      public void run() {
+        TargetType.startConstructorAccess().withParameterTypes((Class<?>[]) null).in(Person.class).info();
+      }
+    });
+  }
+
+  @Test(expected = ReflectionError.class)
+  public void should_throw_error_if_constructor_was_not_found() {
+    Class<Integer> illegalType = Integer.class;
+    TargetType.startConstructorAccess().withParameterTypes(illegalType).in(Person.class);
+  }
+
+  @Test(expected = IllegalArgumentException.class)
+  public void should_throw_error_if_instance_was_not_created() {
+    int illegalArg = 8;
+    TargetType.startConstructorAccess().withParameterTypes(String.class).in(Person.class).newInstance(illegalArg);
+  }
+
+  @Test
+  public void should_rethrow_RuntimeException_thrown_by_constructor() {
+    expectIllegalArgumentException("The name of a person cannot be a number").on(new CodeToTest() {
+      public void run() {
+        TargetType.startConstructorAccess().withParameterTypes(int.class).in(Person.class).newInstance(8);
+      }
+    });
+  }
+
+  @Test
+  public void should_wrap_with_a_ReflectionError_the_checked_Exception_thrown_by_constructor() {
+    try {
+      TargetType.startConstructorAccess().withParameterTypes(Person.class).in(Person.class).newInstance(new Person());
+      fail("Expecting an ReflectionError");
+    } catch (ReflectionError e) {
+      Throwable cause = e.getCause();
+      assertTrue(cause instanceof Exception);
+      assertEquals("A person cannot be created from another person", cause.getMessage());
+    }
+  }
+}
diff --git a/src/test/java/org/fest/reflect/core/FEST68_CatchingWrongExceptions_Test.java b/src/test/java/org/fest/reflect/core/FEST68_CatchingWrongExceptions_Test.java
new file mode 100644
index 0000000..010f8fb
--- /dev/null
+++ b/src/test/java/org/fest/reflect/core/FEST68_CatchingWrongExceptions_Test.java
@@ -0,0 +1,60 @@
+/*
+ * Created on Mar 19, 2009
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2009 the original author or authors.
+ */
+package org.fest.reflect.core;
+
+import static org.fest.reflect.core.Reflection.constructor;
+import static org.fest.reflect.core.Reflection.method;
+
+import org.junit.Test;
+
+/**
+ * Tests for <a href="http://jira.codehaus.org/browse/FEST-68" target="_blank">FEST-68</a>.
+ * 
+ * @author Francis ANDRE
+ * @author Alex Ruiz
+ */
+public class FEST68_CatchingWrongExceptions_Test {
+
+  @Test(expected = MyRuntimeException.class)
+  public void should_not_catch_RuntimeException_when_calling_method() {
+    Main main = new Main();
+    method("set").in(main).invoke();
+  }
+
+  @Test(expected = MyRuntimeException.class)
+  public void should_not_catch_RuntimeException_when_calling_constructor() {
+    constructor().withParameterTypes(String.class).in(Main.class).newInstance("Hello");
+  }
+
+  static class MyRuntimeException extends RuntimeException {
+    private static final long serialVersionUID = 1L;
+
+    public MyRuntimeException(String text) {
+      super(text);
+    }
+  }
+
+  public static class Main {
+    public Main() {}
+
+    public Main(String hello) {
+      throw new MyRuntimeException("set");
+    }
+
+    public void set() {
+      throw new MyRuntimeException("set");
+    }
+  }
+}
diff --git a/src/test/java/org/fest/reflect/core/Reflection_Test.java b/src/test/java/org/fest/reflect/core/Reflection_Test.java
new file mode 100644
index 0000000..e842599
--- /dev/null
+++ b/src/test/java/org/fest/reflect/core/Reflection_Test.java
@@ -0,0 +1,81 @@
+/*
+ * Created on May 18, 2007
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2007-2009 the original author or authors.
+ */
+package org.fest.reflect.core;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+import org.fest.reflect.beanproperty.PropertyName;
+import org.fest.reflect.constructor.TargetType;
+import org.fest.reflect.field.FieldName;
+import org.fest.reflect.field.StaticFieldName;
+import org.fest.reflect.innerclass.StaticInnerClassName;
+import org.fest.reflect.method.MethodName;
+import org.fest.reflect.method.StaticMethodName;
+import org.fest.reflect.type.Type;
+
+/**
+ * Tests for <code>{@link Reflection}</code>.
+ * 
+ * @author Alex Ruiz
+ * @author Yvonne Wang
+ */
+public class Reflection_Test {
+
+  @Test
+  public void should_return_fluent_interface_for_constructor() {
+    verifyTypesAreEqual(TargetType.class, Reflection.constructor());
+  }
+
+  @Test
+  public void should_return_fluent_interface_for_field() {
+    verifyTypesAreEqual(FieldName.class, Reflection.field("foo"));
+  }
+
+  @Test
+  public void should_return_fluent_interface_for_static_field() {
+    verifyTypesAreEqual(StaticFieldName.class, Reflection.staticField("foo"));
+  }
+
+  @Test
+  public void should_return_fluent_interface_for_method() {
+    verifyTypesAreEqual(MethodName.class, Reflection.method("foo"));
+  }
+
+  @Test
+  public void should_return_fluent_interface_for_static_method() {
+    verifyTypesAreEqual(StaticMethodName.class, Reflection.staticMethod("foo"));
+  }
+
+  @Test
+  public void should_return_fluent_interface_for_type() {
+    verifyTypesAreEqual(Type.class, Reflection.type("foo"));
+  }
+
+  @Test
+  public void should_return_fluent_interface_for_static_inner_class() {
+    verifyTypesAreEqual(StaticInnerClassName.class, Reflection.staticInnerClass("foo"));
+  }
+
+  @Test
+  public void should_return_fluent_interface_for_property() {
+    verifyTypesAreEqual(PropertyName.class, Reflection.property("foo"));
+  }
+
+  private void verifyTypesAreEqual(Class<?> expected, Object o) {
+    assertEquals(expected, o.getClass());
+  }
+}
diff --git a/src/test/java/org/fest/reflect/field/FieldDecoratorCombinedTest.java b/src/test/java/org/fest/reflect/field/FieldDecoratorCombinedTest.java
new file mode 100644
index 0000000..049e360
--- /dev/null
+++ b/src/test/java/org/fest/reflect/field/FieldDecoratorCombinedTest.java
@@ -0,0 +1,145 @@
+/*
+ * Created on Mar 19, 2012
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2006-2009 the original author or authors.
+ */
+package org.fest.reflect.field;
+
+import static org.fest.reflect.core.Reflection.field;
+
+import static org.mockito.Matchers.*;
+import static org.mockito.Mockito.*;
+
+import org.junit.Test;
+
+/**
+ * Tests returning decorator result in case of a decorator exceptions
+ * @author Ivan Hristov
+ * 
+ */
+public class FieldDecoratorCombinedTest {
+
+  public interface IUploadFileService {
+    Boolean upload(String file, String destination) throws CustomeException;
+  }
+
+  public interface INotificationService {
+    void notify(String msg);
+  }
+
+  @SuppressWarnings("serial")
+  public class CustomeException extends RuntimeException {
+    public CustomeException() {
+      super("This is a test exception");
+    }
+  }
+
+  private class FileManager {
+
+    private static final String DEFAULT_DESTINATION = "http://example.org/default/destination/";
+
+    private final IUploadFileService uploadFileService;
+    private INotificationService notificationService;
+
+    public FileManager() {
+      this.uploadFileService = new IUploadFileService() {
+
+        public Boolean upload(String file, String destination) {
+          return false;
+        }
+      };
+    }
+
+    public void manage(String fileName) {
+      notificationService.notify("Upload successful? : " + uploadFileService.upload(fileName, DEFAULT_DESTINATION));
+    }
+  }
+
+  @Test
+  public void should_pre_decorate_field_returning_decorator_result_ignoring_custom_exception_in_decorator() {
+    // GIVEN
+    IUploadFileService uploadFileServiceMock = mock(IUploadFileService.class);
+    INotificationService notificationServiceMock = mock(INotificationService.class);
+
+    when(uploadFileServiceMock.upload(anyString(), anyString())).thenThrow(new CustomeException());
+
+    FileManager fileManager = new FileManager();
+
+    field("uploadFileService").ofType(IUploadFileService.class)//
+        .in(fileManager).preDecorateWith(uploadFileServiceMock)//
+        .returningDecoratorResult().ignoringDecoratorExceptionsOfType(CustomeException.class);
+
+    field("notificationService").ofType(INotificationService.class)//
+        .in(fileManager).set(notificationServiceMock);
+
+    // WHEN
+    String fileName = "testFileName";
+    fileManager.manage(fileName);
+
+    // THEN
+    verify(uploadFileServiceMock, times(1)).upload(eq("testFileName"), anyString());
+    verify(notificationServiceMock, times(1)).notify(eq("Upload successful? : null"));
+  }
+
+  @Test
+  public void should_post_decorate_field_returning_decorator_result_ignoring_decorator_exceptions() {
+    // GIVEN
+    IUploadFileService uploadFileServiceMock = mock(IUploadFileService.class);
+    INotificationService notificationServiceMock = mock(INotificationService.class);
+
+    when(uploadFileServiceMock.upload(anyString(), anyString())).thenThrow(new RuntimeException());
+
+    FileManager fileManager = new FileManager();
+
+    field("uploadFileService").ofType(IUploadFileService.class)//
+        .in(fileManager).postDecorateWith(uploadFileServiceMock)//
+        .returningDecoratorResult().ignoringDecoratorExceptions();
+
+    field("notificationService").ofType(INotificationService.class)//
+        .in(fileManager).set(notificationServiceMock);
+
+    // WHEN
+    String fileName = "testFileName";
+    fileManager.manage(fileName);
+
+    // THEN
+    verify(uploadFileServiceMock, times(1)).upload(eq("testFileName"), anyString());
+    verify(notificationServiceMock, times(1)).notify(eq("Upload successful? : null"));
+  }
+
+  @Test
+  public void should_pre_and_post_decorate_field_returning_decorator_result_ignoring_decorator_exceptions() {
+    // GIVEN
+    IUploadFileService uploadFileServiceMock = mock(IUploadFileService.class);
+    INotificationService notificationServiceMock = mock(INotificationService.class);
+
+    when(uploadFileServiceMock.upload(anyString(), anyString())).thenThrow(new RuntimeException()).thenThrow(
+        new CustomeException());
+
+    FileManager fileManager = new FileManager();
+
+    field("uploadFileService").ofType(IUploadFileService.class).in(fileManager).preDecorateWith(uploadFileServiceMock)
+        .ignoringDecoratorExceptions().returningDecoratorResult().postDecorateWith(uploadFileServiceMock)
+        .ignoringDecoratorExceptionsOfType(CustomeException.class).returningDecoratorResult();
+
+    field("notificationService").ofType(INotificationService.class).in(fileManager).set(notificationServiceMock);
+
+    // WHEN
+    String fileName = "testFileName";
+    fileManager.manage(fileName);
+
+    // THEN
+    verify(uploadFileServiceMock, times(2)).upload(eq("testFileName"), anyString());
+    verify(notificationServiceMock, times(1)).notify(eq("Upload successful? : null"));
+  }
+
+}
diff --git a/src/test/java/org/fest/reflect/field/FieldDecoratorIgnoreExceptionTest.java b/src/test/java/org/fest/reflect/field/FieldDecoratorIgnoreExceptionTest.java
new file mode 100644
index 0000000..6d8d0c6
--- /dev/null
+++ b/src/test/java/org/fest/reflect/field/FieldDecoratorIgnoreExceptionTest.java
@@ -0,0 +1,204 @@
+/*
+ * Created on Mar 19, 2012
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2006-2009 the original author or authors.
+ */
+package org.fest.reflect.field;
+
+import static org.fest.reflect.core.Reflection.field;
+
+import static org.mockito.Matchers.*;
+import static org.mockito.Mockito.*;
+
+import java.net.SocketTimeoutException;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.matchers.JUnitMatchers;
+import org.junit.rules.ExpectedException;
+
+/**
+ * 
+ * @author Ivan Hristov
+ * 
+ */
+public class FieldDecoratorIgnoreExceptionTest {
+
+  @Rule
+  public ExpectedException expectedException = ExpectedException.none();
+
+  public interface IUploadFileService {
+    Boolean upload(String file, String destination) throws SocketTimeoutException;
+  }
+
+  public interface INotifierService {
+    void notify(String msg);
+  }
+
+  private class FileManager {
+
+    private static final String DEFAULT_DESTINATION = "http://example.org/default/destination/";
+
+    private final IUploadFileService uploadFileService;
+    private INotifierService notifierService;
+
+    public FileManager() {
+      this.uploadFileService = new IUploadFileService() {
+
+        public Boolean upload(String file, String destination) {
+          return false;
+        }
+      };
+    }
+
+    public void manage(String fileName) throws SocketTimeoutException {
+      if (uploadFileService.upload(fileName, DEFAULT_DESTINATION)) {
+        System.out.println("File " + fileName + " sent to " + DEFAULT_DESTINATION);
+      } else {
+        notifierService.notify("Unable to send msg!");
+      }
+    }
+  }
+
+  @Test
+  public void should_not_ignore_pre_decorator_exceptions() throws SocketTimeoutException {
+    // GIVEN
+    expectedException.expect(SocketTimeoutException.class);
+    String expectedExceptionMsg = "Expected test exception";
+    expectedException.expectMessage(JUnitMatchers.containsString(expectedExceptionMsg));
+
+    IUploadFileService uploadFileServiceMock = mock(IUploadFileService.class);
+    INotifierService notifierServiceMock = mock(INotifierService.class);
+
+    when(uploadFileServiceMock.upload(anyString(), anyString()))//
+        .thenThrow(new SocketTimeoutException(expectedExceptionMsg));
+
+    FileManager fileManager = new FileManager();
+
+    field("uploadFileService").ofType(IUploadFileService.class)//
+        .in(fileManager).preDecorateWith(uploadFileServiceMock).ignoringDecoratorExceptions();
+
+    field("notifierService").ofType(INotifierService.class).in(fileManager).set(notifierServiceMock);
+
+    // WHEN
+    String fileName = "testFileName";
+    fileManager.manage(fileName);
+
+    // THEN there should be an exception
+  }
+
+  @Test
+  public void should_not_ignore_post_decorator_exceptions() throws SocketTimeoutException {
+    // GIVEN
+    expectedException.expect(SocketTimeoutException.class);
+    String expectedExceptionMsg = "Expected test exception";
+    expectedException.expectMessage(JUnitMatchers.containsString(expectedExceptionMsg));
+
+    IUploadFileService uploadFileServiceMock = mock(IUploadFileService.class);
+    INotifierService notifierServiceMock = mock(INotifierService.class);
+
+    when(uploadFileServiceMock.upload(anyString(), anyString()))//
+        .thenThrow(new SocketTimeoutException(expectedExceptionMsg));
+
+    FileManager fileManager = new FileManager();
+
+    field("uploadFileService").ofType(IUploadFileService.class)//
+        .in(fileManager).postDecorateWith(uploadFileServiceMock).ignoringDecoratorExceptions();
+
+    field("notifierService").ofType(INotifierService.class).in(fileManager).set(notifierServiceMock);
+
+    // WHEN
+    String fileName = "testFileName";
+    fileManager.manage(fileName);
+
+    // THEN there should be an exception
+  }
+
+  @Test
+  public void should_pre_decorate_field_ignoring_decorator_exceptions() throws SocketTimeoutException {
+    // GIVEN
+    IUploadFileService uploadFileServiceMock = mock(IUploadFileService.class);
+    INotifierService notifierServiceMock = mock(INotifierService.class);
+
+    when(uploadFileServiceMock.upload(anyString(), anyString()))//
+        .thenThrow(new RuntimeException("Expected test exception"));
+
+    FileManager fileManager = new FileManager();
+
+    field("uploadFileService").ofType(IUploadFileService.class)//
+        .in(fileManager).preDecorateWith(uploadFileServiceMock).ignoringDecoratorExceptions();
+
+    field("notifierService").ofType(INotifierService.class).in(fileManager).set(notifierServiceMock);
+
+    // WHEN
+    String fileName = "testFileName";
+    fileManager.manage(fileName);
+
+    // THEN
+    verify(notifierServiceMock, times(1)).notify(eq("Unable to send msg!"));
+  }
+
+  @Test
+  public void should_post_decorate_field_ignoring_decorator_exceptions() throws SocketTimeoutException {
+    // GIVEN
+    IUploadFileService uploadFileServiceMock = mock(IUploadFileService.class);
+    INotifierService notifierServiceMock = mock(INotifierService.class);
+
+    when(uploadFileServiceMock.upload(anyString(), anyString()))//
+        .thenThrow(new RuntimeException("Expected test exception"));
+
+    FileManager fileManager = new FileManager();
+
+    field("uploadFileService").ofType(IUploadFileService.class)//
+        .in(fileManager).postDecorateWith(uploadFileServiceMock).ignoringDecoratorExceptions();
+
+    field("notifierService").ofType(INotifierService.class).in(fileManager).set(notifierServiceMock);
+
+    // WHEN
+    String fileName = "testFileName";
+    fileManager.manage(fileName);
+
+    // THEN
+    verify(uploadFileServiceMock, times(1)).upload(eq("testFileName"), anyString());
+    verify(notifierServiceMock, times(1)).notify(eq("Unable to send msg!"));
+  }
+
+  @Test
+  public void should_pre_and_post_decorate_field_ignoring_decorator_exceptions() throws SocketTimeoutException {
+    // GIVEN
+    IUploadFileService uploadFileServiceMock = mock(IUploadFileService.class);
+    INotifierService notifierServiceMock = mock(INotifierService.class);
+
+    when(uploadFileServiceMock.upload(anyString(), anyString()))//
+        .thenThrow(new SocketTimeoutException("Expected test exception"))//
+        .thenThrow(new RuntimeException("Expected test exception"))//
+        .thenThrow(new RuntimeException("Expected test exception"));
+
+    FileManager fileManager = new FileManager();
+
+    field("uploadFileService").ofType(IUploadFileService.class).in(fileManager)//
+        .preDecorateWith(uploadFileServiceMock).ignoringDecoratorExceptions()//
+        .postDecorateWith(uploadFileServiceMock).ignoringDecoratorExceptions()//
+        .preDecorateWith(uploadFileServiceMock).ignoringDecoratorExceptionsOfType(SocketTimeoutException.class);
+
+    field("notifierService").ofType(INotifierService.class).in(fileManager).set(notifierServiceMock);
+
+    // WHEN
+    String fileName = "testFileName";
+    fileManager.manage(fileName);
+
+    // THEN
+    verify(uploadFileServiceMock, times(3)).upload(eq("testFileName"), anyString());
+    verify(notifierServiceMock, times(1)).notify(eq("Unable to send msg!"));
+  }
+
+}
diff --git a/src/test/java/org/fest/reflect/field/FieldDecoratorReturningDecoratorResultTest.java b/src/test/java/org/fest/reflect/field/FieldDecoratorReturningDecoratorResultTest.java
new file mode 100644
index 0000000..fc5dece
--- /dev/null
+++ b/src/test/java/org/fest/reflect/field/FieldDecoratorReturningDecoratorResultTest.java
@@ -0,0 +1,214 @@
+/*
+ * Created on Mar 20, 2012
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2006-2009 the original author or authors.
+ */
+package org.fest.reflect.field;
+
+import static org.fest.reflect.core.Reflection.field;
+
+import static org.mockito.Matchers.*;
+import static org.mockito.Mockito.*;
+
+import org.junit.Test;
+
+/**
+ * 
+ * @author Ivan Hristov
+ * 
+ */
+public class FieldDecoratorReturningDecoratorResultTest {
+
+  public interface IUploadFileService {
+    String upload(String file, String destination);
+  }
+
+  public interface INotificationService {
+    void notify(String msg);
+  }
+
+  private class FileManager {
+
+    private static final String DEFAULT_DESTINATION = "http://example.org/default/destination/";
+
+    private final IUploadFileService uploadFileService;
+    private INotificationService notificationService;
+
+    public FileManager() {
+      this.uploadFileService = new IUploadFileService() {
+
+        public String upload(String file, String destination) {
+          return "Default result";
+        }
+      };
+    }
+
+    public void manage(String fileName) {
+      notificationService.notify(uploadFileService.upload(fileName, DEFAULT_DESTINATION));
+    }
+  }
+
+  @Test
+  public void should_pre_decorate_field_and_return_decorator_result() {
+    // GIVEN
+    IUploadFileService uploadFileServiceMock = mock(IUploadFileService.class);
+    INotificationService notificationServiceMock = mock(INotificationService.class);
+
+    String expectedResult = "pre-decorator result";
+    when(uploadFileServiceMock.upload(anyString(), anyString())).thenReturn(expectedResult);
+
+    FileManager fileManager = new FileManager();
+
+    field("uploadFileService").ofType(IUploadFileService.class)//
+        .in(fileManager).preDecorateWith(uploadFileServiceMock).returningDecoratorResult();
+
+    field("notificationService").ofType(INotificationService.class).in(fileManager).set(notificationServiceMock);
+
+    // WHEN
+    String fileName = "testFileName";
+    fileManager.manage(fileName);
+
+    // THEN
+    verify(uploadFileServiceMock, times(1)).upload(eq("testFileName"), anyString());
+    verify(notificationServiceMock, times(1)).notify(eq(expectedResult));
+  }
+
+  @Test
+  public void should_post_decorate_field_and_return_decorator_result() {
+    // GIVEN
+    IUploadFileService uploadFileServiceMock = mock(IUploadFileService.class);
+    INotificationService notificationServiceMock = mock(INotificationService.class);
+
+    String expectedResult = "post-decorator result";
+    when(uploadFileServiceMock.upload(anyString(), anyString())).thenReturn(expectedResult);
+
+    FileManager fileManager = new FileManager();
+
+    field("uploadFileService").ofType(IUploadFileService.class)//
+        .in(fileManager).postDecorateWith(uploadFileServiceMock).returningDecoratorResult();
+
+    field("notificationService").ofType(INotificationService.class).in(fileManager).set(notificationServiceMock);
+
+    // WHEN
+    String fileName = "testFileName";
+    fileManager.manage(fileName);
+
+    // THEN
+    verify(uploadFileServiceMock, times(1)).upload(eq("testFileName"), anyString());
+    verify(notificationServiceMock, times(1)).notify(eq(expectedResult));
+  }
+
+  @Test
+  public void should_pre_and_post_decorate_field_and_return_pre_decorator_result() {
+    // GIVEN
+    IUploadFileService uploadFileServiceMock = mock(IUploadFileService.class);
+    INotificationService notificationServiceMock = mock(INotificationService.class);
+
+    String expectedResult = "pre-decorator result";
+    when(uploadFileServiceMock.upload(anyString(), anyString()))//
+        .thenReturn(expectedResult).thenReturn("post-decorator result");
+
+    FileManager fileManager = new FileManager();
+
+    field("uploadFileService").ofType(IUploadFileService.class).in(fileManager)//
+        .preDecorateWith(uploadFileServiceMock).returningDecoratorResult().postDecorateWith(uploadFileServiceMock);
+
+    field("notificationService").ofType(INotificationService.class).in(fileManager).set(notificationServiceMock);
+
+    // WHEN
+    String fileName = "testFileName";
+    fileManager.manage(fileName);
+
+    // THEN
+    verify(uploadFileServiceMock, times(2)).upload(eq("testFileName"), anyString());
+    verify(notificationServiceMock, times(1)).notify(eq(expectedResult));
+  }
+
+  @Test
+  public void should_pre_and_post_decorate_field_and_return_post_decorator_result() {
+    // GIVEN
+    IUploadFileService uploadFileServiceMock = mock(IUploadFileService.class);
+    INotificationService notificationServiceMock = mock(INotificationService.class);
+
+    String expectedResult = "post-decorator result";
+    when(uploadFileServiceMock.upload(anyString(), anyString())).thenReturn("pre-decorator result").thenReturn(expectedResult);
+
+    FileManager fileManager = new FileManager();
+
+    field("uploadFileService").ofType(IUploadFileService.class).in(fileManager)//
+        .preDecorateWith(uploadFileServiceMock).postDecorateWith(uploadFileServiceMock).returningDecoratorResult();
+
+    field("notificationService").ofType(INotificationService.class).in(fileManager).set(notificationServiceMock);
+
+    // WHEN
+    String fileName = "testFileName";
+    fileManager.manage(fileName);
+
+    // THEN
+    verify(uploadFileServiceMock, times(2)).upload(eq("testFileName"), anyString());
+    verify(notificationServiceMock, times(1)).notify(eq(expectedResult));
+  }
+
+  @Test
+  public void should_pre_and_post_decorate_field_both_returning_results_but_return_post_decorator_result() {
+    // GIVEN
+    IUploadFileService uploadFileServiceMock = mock(IUploadFileService.class);
+    INotificationService notificationServiceMock = mock(INotificationService.class);
+
+    String expectedResult = "post-decorator result";
+    when(uploadFileServiceMock.upload(anyString(), anyString()))//
+        .thenReturn("pre-decorator result").thenReturn(expectedResult);
+
+    FileManager fileManager = new FileManager();
+
+    field("uploadFileService").ofType(IUploadFileService.class).in(fileManager)//
+        .preDecorateWith(uploadFileServiceMock).returningDecoratorResult()//
+        .postDecorateWith(uploadFileServiceMock).returningDecoratorResult();
+
+    field("notificationService").ofType(INotificationService.class).in(fileManager).set(notificationServiceMock);
+
+    // WHEN
+    String fileName = "testFileName";
+    fileManager.manage(fileName);
+
+    // THEN
+    verify(uploadFileServiceMock, times(2)).upload(eq("testFileName"), anyString());
+    verify(notificationServiceMock, times(1)).notify(eq(expectedResult));
+  }
+
+  @Test
+  public void should_pre_and_post_decorate_field_both_returning_results_but_return_pre_decorator_result() {
+    // GIVEN
+    IUploadFileService uploadFileServiceMock = mock(IUploadFileService.class);
+    INotificationService notificationServiceMock = mock(INotificationService.class);
+
+    String expectedResult = "pre-decorator result";
+    when(uploadFileServiceMock.upload(anyString(), anyString()))//
+        .thenReturn(expectedResult).thenReturn("post-decorator result");
+
+    FileManager fileManager = new FileManager();
+
+    field("uploadFileService").ofType(IUploadFileService.class).in(fileManager)//
+        .postDecorateWith(uploadFileServiceMock).returningDecoratorResult()//
+        .preDecorateWith(uploadFileServiceMock).returningDecoratorResult();
+
+    field("notificationService").ofType(INotificationService.class).in(fileManager).set(notificationServiceMock);
+
+    // WHEN
+    String fileName = "testFileName";
+    fileManager.manage(fileName);
+
+    // THEN
+    verify(uploadFileServiceMock, times(2)).upload(eq("testFileName"), anyString());
+    verify(notificationServiceMock, times(1)).notify(eq(expectedResult));
+  }
+}
diff --git a/src/test/java/org/fest/reflect/field/FieldDecoratorTest.java b/src/test/java/org/fest/reflect/field/FieldDecoratorTest.java
new file mode 100644
index 0000000..23ef773
--- /dev/null
+++ b/src/test/java/org/fest/reflect/field/FieldDecoratorTest.java
@@ -0,0 +1,184 @@
+/*
+ * Created on Mar 19, 2012
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2006-2009 the original author or authors.
+ */
+package org.fest.reflect.field;
+
+import static org.fest.reflect.core.Reflection.field;
+
+import static org.mockito.Matchers.*;
+import static org.mockito.Mockito.*;
+
+import org.junit.Test;
+import org.mockito.InOrder;
+
+/**
+ * 
+ * @author Ivan Hristov
+ * 
+ */
+public class FieldDecoratorTest {
+
+  private static class LogMyName {
+
+    private final ILogger logger = new MySmartLogger(this.getClass());
+    private final String name;
+
+    public LogMyName(String name) {
+      this.name = name;
+    }
+
+    public void logMyName() {
+      logger.info(name);
+    }
+  }
+
+  private static class MySmartLogger implements ILogger {
+    private final Class<?> _clazz;
+
+    public MySmartLogger(Class<?> _clazz) {
+      this._clazz = _clazz;
+    }
+
+    public void info(String infoStr) {
+      System.out.println(_clazz.getSimpleName() + " : " + infoStr);
+    }
+  }
+
+  public interface ILogger {
+    public void info(String infoStr);
+  }
+
+  @Test
+  public void should_pre_decorate_field() {
+    // GIVEN
+    ILogger mySmartLoggerMock = mock(ILogger.class);
+
+    LogMyName logMyName = new LogMyName("FEST");
+
+    field("logger").ofType(ILogger.class).in(logMyName).preDecorateWith(mySmartLoggerMock);
+
+    // WHEN
+    logMyName.logMyName();
+
+    // THEN
+    verify(mySmartLoggerMock, times(1)).info(eq("FEST"));
+  }
+
+  public interface IUploadFileService {
+    boolean upload(String file, String destination);
+  }
+
+  private class FileManager {
+
+    private static final String DEFAULT_DESTINATION = "http://example.org/default/destination/";
+
+    private final IUploadFileService uploadFileService;
+
+    public FileManager() {
+      this.uploadFileService = new IUploadFileService() {
+
+        public boolean upload(String file, String destination) {
+          return false;
+        }
+      };
+    }
+
+    public void manage(String fileName) {
+      if (uploadFileService.upload(fileName, DEFAULT_DESTINATION)) {
+        System.out.println("File " + fileName + " sent to " + DEFAULT_DESTINATION);
+      } else {
+        System.out.println("Unable to sent " + fileName + " to " + DEFAULT_DESTINATION);
+      }
+    }
+  }
+
+  @Test
+  public void should_attach_two_pre_decorators() {
+    // GIVEN
+    IUploadFileService firstUploadFileServiceMock = mock(IUploadFileService.class);
+    IUploadFileService secondUploadFileServiceMock = mock(IUploadFileService.class);
+
+    FileManager fileManager = new FileManager();
+
+    field("uploadFileService").ofType(IUploadFileService.class)//
+        .in(fileManager).preDecorateWith(firstUploadFileServiceMock).preDecorateWith(secondUploadFileServiceMock);
+
+    // WHEN
+    String fileName = "testFileName";
+    fileManager.manage(fileName);
+
+    // THEN
+    InOrder inOrder = inOrder(firstUploadFileServiceMock, secondUploadFileServiceMock);
+    inOrder.verify(secondUploadFileServiceMock, times(1)).upload(eq("testFileName"), anyString());
+    inOrder.verify(firstUploadFileServiceMock, times(1)).upload(eq("testFileName"), anyString());
+  }
+
+  @Test
+  public void should_post_decorate_field() {
+    // GIVEN
+    IUploadFileService uploadFileServiceMock = mock(IUploadFileService.class);
+
+    FileManager fileManager = new FileManager();
+
+    field("uploadFileService").ofType(IUploadFileService.class).in(fileManager).postDecorateWith(uploadFileServiceMock);
+
+    // WHEN
+    String fileName = "testFileName";
+    fileManager.manage(fileName);
+
+    // THEN
+    verify(uploadFileServiceMock, times(1)).upload(eq("testFileName"), anyString());
+  }
+
+  @Test
+  public void should_attach_two_post_decorators() {
+    // GIVEN
+    IUploadFileService firstUploadFileServiceMock = mock(IUploadFileService.class);
+    IUploadFileService secondUploadFileServiceMock = mock(IUploadFileService.class);
+
+    FileManager fileManager = new FileManager();
+
+    field("uploadFileService").ofType(IUploadFileService.class)//
+        .in(fileManager).postDecorateWith(firstUploadFileServiceMock).postDecorateWith(secondUploadFileServiceMock);
+
+    // WHEN
+    String fileName = "testFileName";
+    fileManager.manage(fileName);
+
+    // THEN
+    InOrder inOrder = inOrder(firstUploadFileServiceMock, secondUploadFileServiceMock);
+    inOrder.verify(firstUploadFileServiceMock, times(1)).upload(eq("testFileName"), anyString());
+    inOrder.verify(secondUploadFileServiceMock, times(1)).upload(eq("testFileName"), anyString());
+  }
+
+  @Test
+  public void should_pre_and_post_decorate_field() {
+    // GIVEN
+    IUploadFileService uploadFileServiceMock = mock(IUploadFileService.class);
+
+    FileManager fileManager = new FileManager();
+
+    field("uploadFileService").ofType(IUploadFileService.class).in(fileManager)
+    //
+        .preDecorateWith(uploadFileServiceMock).postDecorateWith(uploadFileServiceMock).preDecorateWith(uploadFileServiceMock);
+
+    // WHEN
+    String fileName = "testFileName";
+    fileManager.manage(fileName);
+
+    // THEN
+    verify(uploadFileServiceMock, times(3)).upload(eq("testFileName"), anyString());
+  }
+
+}
diff --git a/src/test/java/org/fest/reflect/field/Field_field_Test.java b/src/test/java/org/fest/reflect/field/Field_field_Test.java
new file mode 100644
index 0000000..19405c2
--- /dev/null
+++ b/src/test/java/org/fest/reflect/field/Field_field_Test.java
@@ -0,0 +1,157 @@
+/*
+ * Created on May 18, 2007
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2007-2009 the original author or authors.
+ */
+package org.fest.reflect.field;
+
+import static org.fest.reflect.util.ExpectedFailures.expectIllegalArgumentException;
+import static org.fest.reflect.util.ExpectedFailures.expectNullPointerException;
+import static org.fest.reflect.util.ExpectedFailures.expectReflectionError;
+import static org.fest.util.Lists.newArrayList;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.List;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import org.fest.reflect.Jedi;
+import org.fest.reflect.Person;
+import org.fest.reflect.reference.TypeRef;
+import org.fest.test.CodeToTest;
+
+/**
+ * Tests for the fluent interface for accessing fields.
+ * 
+ * @author Alex Ruiz
+ */
+public class Field_field_Test {
+
+  private Person person;
+
+  @Before
+  public void setUp() {
+    person = new Person("Luke");
+  }
+
+  @Test
+  public void should_throw_error_if_field_name_is_null() {
+    expectNullPointerException("The name of the field to access should not be null").on(new CodeToTest() {
+      public void run() {
+        FieldName.beginFieldAccess(null);
+      }
+    });
+  }
+
+  @Test
+  public void should_throw_error_if_field_name_is_empty() {
+    expectIllegalArgumentException("The name of the field to access should not be empty").on(new CodeToTest() {
+      public void run() {
+        FieldName.beginFieldAccess("");
+      }
+    });
+  }
+
+  @Test
+  public void should_throw_error_if_field_type_is_null() {
+    expectNullPointerException("The type of the field to access should not be null").on(new CodeToTest() {
+      public void run() {
+        FieldName.beginFieldAccess("name").ofType((Class<?>) null);
+      }
+    });
+  }
+
+  @Test
+  public void should_throw_error_if_target_is_null() {
+    expectNullPointerException("Target should not be null").on(new CodeToTest() {
+      public void run() {
+        FieldName.beginFieldAccess("name").ofType(String.class).in(null);
+      }
+    });
+  }
+
+  @Test
+  public void should_get_field_value() {
+    String personName = FieldName.beginFieldAccess("name").ofType(String.class).in(person).get();
+    assertEquals("Luke", personName);
+  }
+
+  @Test
+  public void should_set_field_value() {
+    FieldName.beginFieldAccess("name").ofType(String.class).in(person).set("Leia");
+    assertEquals("Leia", person.getName());
+  }
+
+  @Test
+  public void should_return_real_field() {
+    java.lang.reflect.Field field = FieldName.beginFieldAccess("name").ofType(String.class).in(person).info();
+    assertNotNull(field);
+    assertEquals("name", field.getName());
+    assertEquals(String.class, field.getType());
+  }
+
+  @Test
+  public void should_throw_error_if_wrong_field_type_was_specified() {
+    String msg = "The type of the field 'name' in org.fest.reflect.Person should be <java.lang.Integer> but was <java.lang.String>";
+    expectReflectionError(msg).on(new CodeToTest() {
+      public void run() {
+        FieldName.beginFieldAccess("name").ofType(Integer.class).in(person).get();
+      }
+    });
+  }
+
+  @Test
+  public void should_throw_error_if_field_name_is_invalid() {
+    expectReflectionError("Unable to find field 'age' in org.fest.reflect.Person").on(new CodeToTest() {
+      public void run() {
+        FieldName.beginFieldAccess("age").ofType(Integer.class).in(person);
+      }
+    });
+  }
+
+  @Test
+  public void should_get_field_in_super_type() {
+    Jedi jedi = new Jedi("Yoda");
+    String jediName = FieldName.beginFieldAccess("name").ofType(String.class).in(jedi).get();
+    assertEquals("Yoda", jediName);
+  }
+
+  @Test
+  public void should_throw_error_if_TypeRef_is_null() {
+    expectNullPointerException("The type reference of the field to access should not be null").on(new CodeToTest() {
+      public void run() {
+        FieldName.beginFieldAccess("name").ofType((TypeRef<?>) null);
+      }
+    });
+  }
+
+  @Test
+  public void should_use_TypeRef_to_read_field() {
+    Jedi jedi = new Jedi("Yoda");
+    jedi.addPower("heal");
+    List<String> powers = FieldName.beginFieldAccess("powers").ofType(new TypeRef<List<String>>() {}).in(jedi).get();
+    assertEquals(1, powers.size());
+    assertEquals("heal", powers.get(0));
+  }
+
+  @Test
+  public void should_use_TypeRef_to_write_field() {
+    Jedi jedi = new Jedi("Yoda");
+    List<String> powers = newArrayList("heal");
+    FieldName.beginFieldAccess("powers").ofType(new TypeRef<List<String>>() {}).in(jedi).set(powers);
+    assertEquals(1, jedi.powers().size());
+    assertEquals("heal", jedi.powers().get(0));
+  }
+}
diff --git a/src/test/java/org/fest/reflect/field/Field_staticField_Test.java b/src/test/java/org/fest/reflect/field/Field_staticField_Test.java
new file mode 100644
index 0000000..97e15a2
--- /dev/null
+++ b/src/test/java/org/fest/reflect/field/Field_staticField_Test.java
@@ -0,0 +1,151 @@
+/*
+ * Created on Nov 23, 2009
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2009 the original author or authors.
+ */
+package org.fest.reflect.field;
+
+import static org.fest.reflect.util.ExpectedFailures.expectIllegalArgumentException;
+import static org.fest.reflect.util.ExpectedFailures.expectNullPointerException;
+import static org.fest.reflect.util.ExpectedFailures.expectReflectionError;
+import static org.fest.util.Lists.newArrayList;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.List;
+
+import org.junit.Test;
+
+import org.fest.reflect.Jedi;
+import org.fest.reflect.Person;
+import org.fest.reflect.reference.TypeRef;
+import org.fest.test.CodeToTest;
+
+/**
+ * Tests for the fluent interface for accessing static fields.
+ * 
+ * @author Alex Ruiz
+ */
+public class Field_staticField_Test {
+
+  @Test
+  public void should_throw_error_if_static_field_name_is_null() {
+    expectNullPointerException("The name of the static field to access should not be null").on(new CodeToTest() {
+      public void run() {
+        StaticFieldName.beginStaticFieldAccess(null);
+      }
+    });
+  }
+
+  @Test
+  public void should_throw_error_if_static_field_name_is_empty() {
+    expectIllegalArgumentException("The name of the static field to access should not be empty").on(new CodeToTest() {
+      public void run() {
+        StaticFieldName.beginStaticFieldAccess("");
+      }
+    });
+  }
+
+  @Test
+  public void should_throw_error_if_static_field_type_is_null() {
+    expectNullPointerException("The type of the static field to access should not be null").on(new CodeToTest() {
+      public void run() {
+        StaticFieldName.beginStaticFieldAccess("name").ofType((Class<?>) null);
+      }
+    });
+  }
+
+  @Test
+  public void should_throw_error_if_target_is_null() {
+    expectNullPointerException("Target should not be null").on(new CodeToTest() {
+      public void run() {
+        StaticFieldName.beginStaticFieldAccess("age").ofType(int.class).in(null);
+      }
+    });
+  }
+
+  @Test
+  public void should_get_static_field_value() {
+    Person.setCount(6);
+    int count = StaticFieldName.beginStaticFieldAccess("count").ofType(int.class).in(Person.class).get();
+    assertEquals(6, count);
+  }
+
+  @Test
+  public void should_set_static_field_value() {
+    StaticFieldName.beginStaticFieldAccess("count").ofType(int.class).in(Person.class).set(8);
+    assertEquals(8, Person.getCount());
+  }
+
+  @Test
+  public void should_return_real_static_field() {
+    java.lang.reflect.Field field = StaticFieldName.beginStaticFieldAccess("count").ofType(int.class).in(Person.class).info();
+    assertNotNull(field);
+    assertEquals("count", field.getName());
+    assertEquals(int.class, field.getType());
+
+  }
+
+  @Test
+  public void should_throw_error_if_wrong_static_field_type_was_specified() {
+    String msg = "The type of the field 'count' in org.fest.reflect.Person should be <java.lang.Float> but was <int>";
+    expectReflectionError(msg).on(new CodeToTest() {
+      public void run() {
+        StaticFieldName.beginStaticFieldAccess("count").ofType(Float.class).in(Person.class).get();
+      }
+    });
+  }
+
+  @Test
+  public void should_throw_error_if_static_field_name_is_invalid() {
+    expectReflectionError("Unable to find field 'age' in org.fest.reflect.Person").on(new CodeToTest() {
+      public void run() {
+        StaticFieldName.beginStaticFieldAccess("age").ofType(int.class).in(Person.class);
+      }
+    });
+  }
+
+  @Test
+  public void should_get_static_field_in_super_type() {
+    Person.setCount(8);
+    int count = StaticFieldName.beginStaticFieldAccess("count").ofType(int.class).in(Person.class).get();
+    assertEquals(8, count);
+  }
+
+  @Test
+  public void should_throw_error_if_TypeRef_is_null() {
+    String msg = "The type reference of the static field to access should not be null";
+    expectNullPointerException(msg).on(new CodeToTest() {
+      public void run() {
+        StaticFieldName.beginStaticFieldAccess("name").ofType((TypeRef<?>) null);
+      }
+    });
+  }
+
+  @Test
+  public void should_use_TypeRef_to_read_static_field() {
+    Jedi.addCommonPower("jump");
+    List<String> powers = StaticFieldName.beginStaticFieldAccess("commonPowers").ofType(new TypeRef<List<String>>() {})
+        .in(Jedi.class).get();
+    assertEquals(1, powers.size());
+    assertEquals("jump", powers.get(0));
+  }
+
+  @Test
+  public void should_use_TypeRef_to_write_static_field() {
+    List<String> powers = newArrayList("jump");
+    StaticFieldName.beginStaticFieldAccess("commonPowers").ofType(new TypeRef<List<String>>() {}).in(Jedi.class).set(powers);
+    assertEquals(1, Jedi.commonPowers().size());
+    assertEquals("jump", Jedi.commonPowers().get(0));
+  }
+}
diff --git a/src/test/java/org/fest/reflect/field/NestedFieldTest.java b/src/test/java/org/fest/reflect/field/NestedFieldTest.java
new file mode 100644
index 0000000..b3a5a30
--- /dev/null
+++ b/src/test/java/org/fest/reflect/field/NestedFieldTest.java
@@ -0,0 +1,197 @@
+/*
+ * Created on Apr 8, 2012
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2006-2009 the original author or authors.
+ */
+package org.fest.reflect.field;
+
+import static org.fest.reflect.core.Reflection.field;
+import static org.fest.util.Lists.newArrayList;
+
+import static org.junit.Assert.assertSame;
+import static org.mockito.Mockito.*;
+
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.matchers.JUnitMatchers;
+import org.junit.rules.ExpectedException;
+
+import org.fest.reflect.exception.ReflectionError;
+import org.fest.reflect.reference.TypeRef;
+
+/**
+ * @author Ivan Hristov
+ * 
+ */
+public class NestedFieldTest {
+
+  @Rule
+  public ExpectedException expectedException = ExpectedException.none();
+
+  private static final class BusinessService {
+    private final NotificationService notificationService;
+
+    public BusinessService() {
+      this.notificationService = new NotificationService();
+    }
+
+    public void doLogic() {
+      notificationService.save();
+    }
+
+    public NotificationService getNotificationService() {
+      return notificationService;
+    }
+    // ...
+  }
+
+  private static final class NotificationService {
+    private final Logger logger = new Logger();
+    private final IClientStatusDao clientStatusDao;
+
+    public NotificationService() {
+      this.clientStatusDao = new ClientStatusDao();
+    }
+
+    // ...
+
+    public void save() {
+      clientStatusDao.update();
+    }
+
+    public Logger getLogger() {
+      return logger;
+    }
+  }
+
+  private static class Logger {
+    // ...
+  }
+
+  private static interface IClientStatusDao {
+    void update();
+  }
+
+  private static class ClientStatusDao implements IClientStatusDao {
+    private final Session session;
+    @SuppressWarnings("unused")
+    private final List<String> listOfNames = newArrayList("Ivan", "Joel", "Alex");
+
+    public ClientStatusDao() {
+      this.session = new SessionImpl();
+    }
+
+    public void update() {
+      session.manageSession();
+    }
+  }
+
+  private static class SessionImpl implements Session {
+    private final SessionMonitor sessionMonitor = new SessionMonitor();
+
+    public void manageSession() {
+      sessionMonitor.monitor();
+      // logic goes here
+    }
+
+  }
+
+  private static interface Session {
+    void manageSession();
+  }
+
+  private static class SessionMonitor {
+    public void monitor() {
+      // monitoring logic here
+    }
+  }
+
+  @Test
+  public void shouldSetOneLevelNestedLoggerField() {
+    // GIVEN
+    BusinessService businessService = new BusinessService();
+    Logger loggerMock = mock(Logger.class);
+
+    // WHEN
+    field("notificationService.logger").ofType(Logger.class).in(businessService).set(loggerMock);
+
+    // THEN
+    assertSame(businessService.getNotificationService().getLogger(), loggerMock);
+  }
+
+  @Test
+  public void shouldThrowExceptionBecauseOfWrongOrder() {
+
+    expectedException.expect(ReflectionError.class);
+    expectedException.expectMessage(JUnitMatchers.containsString(//
+        "Unable to find field 'clientStatusDao' in org.fest.reflect.field.NestedFieldTest$BusinessService"));
+
+    // GIVEN
+    BusinessService businessService = new BusinessService();
+    Session sessionMock = mock(Session.class);
+
+    field("clientStatusDao.notificationService.session").ofType(Session.class).in(businessService).set(sessionMock);
+
+    // WHEN
+    businessService.doLogic();
+
+    // THEN
+    verify(sessionMock, times(1)).manageSession();
+  }
+
+  @Test
+  public void shouldSetSecondLevelNestedSessionField() {
+    // GIVEN
+    BusinessService businessService = new BusinessService();
+    Session sessionMock = mock(Session.class);
+
+    field("notificationService.clientStatusDao.session").ofType(Session.class).in(businessService).set(sessionMock);
+
+    // WHEN
+    businessService.doLogic();
+
+    // THEN
+    verify(sessionMock, times(1)).manageSession();
+  }
+
+  @Test
+  public void shouldGetSecondLevelNestedListOfNamesField() {
+    // GIVEN
+    BusinessService businessService = new BusinessService();
+
+    // WHEN
+    List<String> listOfNames = field("notificationService.clientStatusDao.listOfNames").ofType(new TypeRef<List<String>>() {})
+        .in(businessService).get();
+
+    // THEN
+    Assert.assertThat(listOfNames, JUnitMatchers.hasItems("Ivan", "Joel", "Alex"));
+  }
+
+  @Test
+  public void shouldSetThirdLevelNestedSessionFactoryField() {
+    // GIVEN
+    BusinessService businessService = new BusinessService();
+    SessionMonitor sessionMonitorMock = mock(SessionMonitor.class);
+
+    field("notificationService.clientStatusDao.session.sessionMonitor").ofType(SessionMonitor.class)//
+        .in(businessService).set(sessionMonitorMock);
+
+    // WHEN
+    businessService.doLogic();
+
+    // THEN
+    verify(sessionMonitorMock, times(1)).monitor();
+  }
+}
diff --git a/src/test/java/org/fest/reflect/field/decorator/TestRuntimeExceptionShield.java b/src/test/java/org/fest/reflect/field/decorator/TestRuntimeExceptionShield.java
new file mode 100644
index 0000000..9f7dcc8
--- /dev/null
+++ b/src/test/java/org/fest/reflect/field/decorator/TestRuntimeExceptionShield.java
@@ -0,0 +1,79 @@
+/*
+ * Created on Mar 19, 2012
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2006-2009 the original author or authors.
+ */
+package org.fest.reflect.field.decorator;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.lang.reflect.Proxy;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.matchers.JUnitMatchers;
+import org.junit.rules.ExpectedException;
+
+/**
+ * @author Ivan Hristov
+ * 
+ */
+public class TestRuntimeExceptionShield {
+
+  @Rule
+  public ExpectedException expectedException = ExpectedException.none();
+
+  interface ITestService {
+    boolean test() throws IllegalAccessError;
+  }
+
+  @Test
+  public void shouldShieldFromRuntimeException() {
+    // GIVEN
+    ITestService testServiceMock = mock(ITestService.class);
+    when(testServiceMock.test()).thenThrow(new RuntimeException("Expected test exception"));
+
+    RuntimeExceptionShield runtimeExceptionShield = new RuntimeExceptionShield(testServiceMock, RuntimeException.class);
+
+    ITestService proxyObject = (ITestService) Proxy.newProxyInstance(testServiceMock.getClass().getClassLoader(),//
+        new Class[] { ITestService.class }, runtimeExceptionShield);
+
+    // WHEN
+    proxyObject.test();
+
+    // THEN no exception should happen
+    verify(testServiceMock, times(1)).test();
+  }
+
+  @Test
+  public void shouldNotShieldFromNonRuntimeException() {
+    // GIVEN
+    expectedException.expect(IllegalAccessError.class);
+    expectedException.expectMessage(JUnitMatchers.containsString("Expected test error"));
+
+    ITestService testServiceMock = mock(ITestService.class);
+    when(testServiceMock.test()).thenThrow(new IllegalAccessError("Expected test error"));
+
+    RuntimeExceptionShield runtimeExceptionShield = new RuntimeExceptionShield(testServiceMock, RuntimeException.class);
+
+    ITestService proxyObject = (ITestService) Proxy.newProxyInstance(testServiceMock.getClass().getClassLoader(),//
+        new Class[] { ITestService.class }, runtimeExceptionShield);
+
+    // WHEN
+    proxyObject.test();
+
+    // THEN there should be an error
+  }
+}
diff --git a/src/test/java/org/fest/reflect/innerclass/OuterClass.java b/src/test/java/org/fest/reflect/innerclass/OuterClass.java
new file mode 100644
index 0000000..9e7e75d
--- /dev/null
+++ b/src/test/java/org/fest/reflect/innerclass/OuterClass.java
@@ -0,0 +1,42 @@
+/*
+ * Created on Jan 25, 2009
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2009 the original author or authors.
+ */
+package org.fest.reflect.innerclass;
+
+/**
+ * Understands SOMETHING DUMMY.
+ * 
+ * @author Alex Ruiz
+ */
+public class OuterClass {
+
+  public static class PublicInnerClass {}
+
+  protected static class ProtectedInnerClass {}
+
+  static class PackageInnerClass {}
+
+  @SuppressWarnings("unused")
+  private static class PrivateInnerClass {
+    private final String name;
+
+    PrivateInnerClass(String name) {
+      this.name = name;
+    }
+
+    String name() {
+      return name;
+    }
+  }
+}
diff --git a/src/test/java/org/fest/reflect/innerclass/StaticInnerClass_Test.java b/src/test/java/org/fest/reflect/innerclass/StaticInnerClass_Test.java
new file mode 100644
index 0000000..98a4014
--- /dev/null
+++ b/src/test/java/org/fest/reflect/innerclass/StaticInnerClass_Test.java
@@ -0,0 +1,84 @@
+/*
+ * Created on Jan 25, 2009
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2009 the original author or authors.
+ */
+package org.fest.reflect.innerclass;
+
+import static org.fest.reflect.core.Reflection.constructor;
+import static org.fest.reflect.core.Reflection.field;
+import static org.fest.reflect.core.Reflection.method;
+import static org.fest.reflect.util.ExpectedFailures.expectIllegalArgumentException;
+import static org.fest.reflect.util.ExpectedFailures.expectNullPointerException;
+import static org.fest.reflect.util.ExpectedFailures.expectReflectionError;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+import org.fest.test.CodeToTest;
+
+/**
+ * Tests for the fluent interface for inner classes.
+ * 
+ * @author Alex Ruiz
+ */
+public class StaticInnerClass_Test {
+
+  @Test
+  public void should_throw_error_if_static_inner_class_name_is_null() {
+    expectNullPointerException("The name of the static inner class to access should not be null").on(new CodeToTest() {
+      public void run() {
+        StaticInnerClassName.startStaticInnerClassAccess(null);
+      }
+    });
+  }
+
+  @Test
+  public void should_throw_error_if_static_inner_class_name_is_empty() {
+    expectIllegalArgumentException("The name of the static inner class to access should not be empty").on(new CodeToTest() {
+      public void run() {
+        StaticInnerClassName.startStaticInnerClassAccess("");
+      }
+    });
+  }
+
+  @Test
+  public void should_throw_error_if_declaring_class_is_null() {
+    expectNullPointerException("The declaring class should not be null").on(new CodeToTest() {
+      public void run() {
+        StaticInnerClassName.startStaticInnerClassAccess("Hello").in(null);
+      }
+    });
+  }
+
+  @Test
+  public void should_see_static_inner_class() {
+    Class<?> innerClass = StaticInnerClassName.startStaticInnerClassAccess("PrivateInnerClass").in(OuterClass.class).get();
+    assertTrue(innerClass.getName().contains("PrivateInnerClass"));
+    // make sure we really got the inner classes by creating a new instance and accessing its fields and methods.
+    Object leia = constructor().withParameterTypes(String.class).in(innerClass).newInstance("Leia");
+    assertEquals("Leia", field("name").ofType(String.class).in(leia).get());
+    assertEquals("Leia", method("name").withReturnType(String.class).in(leia).invoke());
+  }
+
+  @Test
+  public void should_return_null_if_static_inner_class_does_not_exist() {
+    String msg = "The static inner class <SomeInnerClass> cannot be found in org.fest.reflect.innerclass.OuterClass";
+    expectReflectionError(msg).on(new CodeToTest() {
+      public void run() {
+        StaticInnerClassName.startStaticInnerClassAccess("SomeInnerClass").in(OuterClass.class).get();
+      }
+    });
+  }
+}
diff --git a/src/test/java/org/fest/reflect/method/Method_method_Test.java b/src/test/java/org/fest/reflect/method/Method_method_Test.java
new file mode 100644
index 0000000..0f8fe39
--- /dev/null
+++ b/src/test/java/org/fest/reflect/method/Method_method_Test.java
@@ -0,0 +1,208 @@
+/*
+ * Created on May 18, 2007
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2007-2009 the original author or authors.
+ */
+package org.fest.reflect.method;
+
+import static org.fest.reflect.util.ExpectedFailures.expectIllegalArgumentException;
+import static org.fest.reflect.util.ExpectedFailures.expectNullPointerException;
+import static org.fest.reflect.util.ExpectedFailures.expectReflectionError;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.List;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import org.fest.reflect.Jedi;
+import org.fest.reflect.exception.ReflectionError;
+import org.fest.reflect.reference.TypeRef;
+import org.fest.test.CodeToTest;
+
+/**
+ * Tests for the fluent interface for accessing methods.
+ * 
+ * @author Yvonne Wang
+ * @author Alex Ruiz
+ */
+public class Method_method_Test {
+
+  private Jedi jedi;
+
+  @Before
+  public void setUp() {
+    jedi = new Jedi("Luke");
+  }
+
+  @Test
+  public void should_throw_error_if_method_name_is_null() {
+    expectNullPointerException("The name of the method to access should not be null").on(new CodeToTest() {
+      public void run() {
+        MethodName.startMethodAccess(null);
+      }
+    });
+  }
+
+  @Test
+  public void should_throw_error_if_method_name_is_empty() {
+    expectIllegalArgumentException("The name of the method to access should not be empty").on(new CodeToTest() {
+      public void run() {
+        MethodName.startMethodAccess("");
+      }
+    });
+  }
+
+  @Test
+  public void should_throw_error_if_method_return_type_is_null() {
+    String msg = "The return type of the method to access should not be null";
+    expectNullPointerException(msg).on(new CodeToTest() {
+      public void run() {
+        MethodName.startMethodAccess("setName").withReturnType((Class<?>) null);
+      }
+    });
+  }
+
+  @Test
+  public void should_throw_error_if_method_return_TypeRef_is_null() {
+    String msg = "The return type reference of the method to access should not be null";
+    expectNullPointerException(msg).on(new CodeToTest() {
+      public void run() {
+        MethodName.startMethodAccess("setName").withReturnType((TypeRef<?>) null);
+      }
+    });
+  }
+
+  @Test
+  public void should_throw_error_if_method_parameter_array_is_null() {
+    String msg = "The array of parameter types for the method to access should not be null";
+    expectNullPointerException(msg).on(new CodeToTest() {
+      public void run() {
+        Class<?>[] parameterTypes = null;
+        MethodName.startMethodAccess("setName").withParameterTypes(parameterTypes);
+      }
+    });
+  }
+
+  @Test
+  public void should_throw_error_if_method_target_is_null() {
+    expectNullPointerException("Target should not be null").on(new CodeToTest() {
+      public void run() {
+        MethodName.startMethodAccess("setName").in(null);
+      }
+    });
+  }
+
+  @Test
+  public void should_call_method_with_args_and_no_return_value() {
+    MethodName.startMethodAccess("setName").withParameterTypes(String.class).in(jedi).invoke("Leia");
+    assertEquals("Leia", jedi.getName());
+  }
+
+  @Test
+  public void should_call_method_with_no_args_and_return_value() {
+    String personName = MethodName.startMethodAccess("getName").withReturnType(String.class).in(jedi).invoke();
+    assertEquals("Luke", personName);
+  }
+
+  @Test
+  public void should_call_method_with_args_and_return_value() {
+    jedi.addPower("healing");
+    String power = MethodName.startMethodAccess("powerAt").withReturnType(String.class).withParameterTypes(int.class).in(jedi)
+        .invoke(0);
+    assertEquals("healing", power);
+  }
+
+  @Test
+  public void should_call_method_with_no_args_and_return_TypeRef() {
+    jedi.addPower("jump");
+    List<String> powers = MethodName.startMethodAccess("powers").withReturnType(new TypeRef<List<String>>() {}).in(jedi).invoke();
+    assertEquals(1, powers.size());
+    assertEquals("jump", powers.get(0));
+  }
+
+  @Test
+  public void should_call_method_with_args_and_return_TypeRef() {
+    jedi.addPower("healing");
+    jedi.addPower("jump");
+    String method = "powersThatStartWith";
+    List<String> powers = MethodName.startMethodAccess(method).withReturnType(new TypeRef<List<String>>() {})
+        .withParameterTypes(String.class).in(jedi).invoke("ju");
+    assertEquals(1, powers.size());
+    assertEquals("jump", powers.get(0));
+  }
+
+  @Test
+  public void should_call_method_with_no_args_and_no_return_value() {
+    assertFalse(jedi.isMaster());
+    MethodName.startMethodAccess("makeMaster").in(jedi).invoke();
+    assertTrue(jedi.isMaster());
+  }
+
+  @Test
+  public void should_return_real_method() {
+    java.lang.reflect.Method method = MethodName.startMethodAccess("setName").withParameterTypes(String.class).in(jedi).info();
+    assertNotNull(method);
+    assertEquals("setName", method.getName());
+    Class<?>[] parameterTypes = method.getParameterTypes();
+    assertEquals(1, parameterTypes.length);
+    assertEquals(String.class, parameterTypes[0]);
+  }
+
+  @Test
+  public void should_throw_error_if_method_name_is_invalid() {
+    String message = "Unable to find method 'getAge' in org.fest.reflect.Jedi with parameter type(s) []";
+    expectReflectionError(message).on(new CodeToTest() {
+      public void run() {
+        String invalidName = "getAge";
+        MethodName.startMethodAccess(invalidName).withReturnType(Integer.class).in(jedi);
+      }
+    });
+  }
+
+  @Test
+  public void should_throw_error_if_args_for_method_are_invalid() {
+    expectIllegalArgumentException("argument type mismatch").on(new CodeToTest() {
+      public void run() {
+        int invalidArg = 8;
+        MethodName.startMethodAccess("setName").withParameterTypes(String.class).in(jedi).invoke(invalidArg);
+      }
+    });
+  }
+
+  @Test
+  public void should_rethrow_RuntimeException_thrown_by_method() {
+    try {
+      MethodName.startMethodAccess("throwRuntimeException").in(jedi).invoke();
+      fail("Expecting an IllegalStateException");
+    } catch (IllegalStateException e) {
+      assertEquals("Somehow I got in an illegal state", e.getMessage());
+    }
+  }
+
+  @Test
+  public void should_wrap_with_a_ReflectionError_the_checked_Exception_thrown_by_method() {
+    try {
+      MethodName.startMethodAccess("throwCheckedException").in(jedi).invoke();
+      fail("Expecting an ReflectionError");
+    } catch (ReflectionError e) {
+      Throwable cause = e.getCause();
+      assertTrue(cause instanceof Exception);
+      assertEquals("I don't know what's wrong", cause.getMessage());
+    }
+  }
+}
diff --git a/src/test/java/org/fest/reflect/method/Method_staticMethod_Test.java b/src/test/java/org/fest/reflect/method/Method_staticMethod_Test.java
new file mode 100644
index 0000000..4840cff
--- /dev/null
+++ b/src/test/java/org/fest/reflect/method/Method_staticMethod_Test.java
@@ -0,0 +1,174 @@
+/*
+ * Created on Nov 23, 2009
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2009 the original author or authors.
+ */
+package org.fest.reflect.method;
+
+import static org.fest.reflect.util.ExpectedFailures.expectIllegalArgumentException;
+import static org.fest.reflect.util.ExpectedFailures.expectNullPointerException;
+import static org.fest.reflect.util.ExpectedFailures.expectReflectionError;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.List;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import org.fest.reflect.Jedi;
+import org.fest.reflect.reference.TypeRef;
+import org.fest.test.CodeToTest;
+
+/**
+ * Tests for the fluent interface for accessing static methods.
+ * 
+ * @author Yvonne Wang
+ * @author Alex Ruiz
+ */
+public class Method_staticMethod_Test {
+
+  @Before
+  public void setUp() {
+    Jedi.clearCommonPowers();
+  }
+
+  @Test
+  public void should_throw_error_if_static_method_name_is_null() {
+    expectNullPointerException("The name of the static method to access should not be null").on(new CodeToTest() {
+      public void run() {
+        StaticMethodName.startStaticMethodAccess(null);
+      }
+    });
+  }
+
+  @Test
+  public void should_throw_error_if_static_method_name_is_empty() {
+    expectIllegalArgumentException("The name of the static method to access should not be empty").on(new CodeToTest() {
+      public void run() {
+        StaticMethodName.startStaticMethodAccess("");
+      }
+    });
+  }
+
+  @Test
+  public void should_throw_error_if_static_method_return_type_is_null() {
+    String msg = "The return type of the static method to access should not be null";
+    expectNullPointerException(msg).on(new CodeToTest() {
+      public void run() {
+        StaticMethodName.startStaticMethodAccess("commonPowerCount").withReturnType((Class<?>) null);
+      }
+    });
+  }
+
+  @Test
+  public void should_throw_error_if_static_method_return_TypeRef_is_null() {
+    String msg = "The return type reference of the static method to access should not be null";
+    expectNullPointerException(msg).on(new CodeToTest() {
+      public void run() {
+        StaticMethodName.startStaticMethodAccess("commonPowerCount").withReturnType((TypeRef<?>) null);
+      }
+    });
+  }
+
+  @Test
+  public void should_throw_error_if_static_method_parameter_array_is_null() {
+    String msg = "The array of parameter types for the static method to access should not be null";
+    expectNullPointerException(msg).on(new CodeToTest() {
+      public void run() {
+        Class<?>[] parameterTypes = null;
+        StaticMethodName.startStaticMethodAccess("commonPowerCount").withParameterTypes(parameterTypes);
+      }
+    });
+  }
+
+  @Test
+  public void should_throw_error_if_static_method_target_is_null() {
+    expectNullPointerException("Target should not be null").on(new CodeToTest() {
+      public void run() {
+        StaticMethodName.startStaticMethodAccess("commonPowerCount").in(null);
+      }
+    });
+  }
+
+  @Test
+  public void should_call_static_method_with_no_args_and_return_value() {
+    Jedi.addCommonPower("Jump");
+    int count = StaticMethodName.startStaticMethodAccess("commonPowerCount").withReturnType(int.class).in(Jedi.class).invoke();
+    assertEquals(Jedi.commonPowerCount(), count);
+  }
+
+  @Test
+  public void should_call_static_method_with_args_and_return_value() {
+    Jedi.addCommonPower("Jump");
+    String power = StaticMethodName.startStaticMethodAccess("commonPowerAt").withReturnType(String.class)
+        .withParameterTypes(int.class).in(Jedi.class).invoke(0);
+    assertEquals("Jump", power);
+  }
+
+  @Test
+  public void should_call_static_method_with_no_args_and_return_TypeRef() {
+    Jedi.addCommonPower("jump");
+    String method = "commonPowers";
+    List<String> powers = StaticMethodName.startStaticMethodAccess(method).withReturnType(new TypeRef<List<String>>() {})
+        .in(Jedi.class).invoke();
+    assertEquals(1, powers.size());
+    assertEquals("jump", powers.get(0));
+  }
+
+  @Test
+  public void should_call_static_method_with_args_and_return_TypeRef() {
+    Jedi.addCommonPower("jump");
+    String method = "commonPowersThatStartWith";
+    List<String> powers = StaticMethodName.startStaticMethodAccess(method).withReturnType(new TypeRef<List<String>>() {})
+        .withParameterTypes(String.class).in(Jedi.class).invoke("ju");
+    assertEquals(1, powers.size());
+    assertEquals("jump", powers.get(0));
+  }
+
+  @Test
+  public void should_call_static_method_with_args_and_no_return_value() {
+    StaticMethodName.startStaticMethodAccess("addCommonPower").withParameterTypes(String.class).in(Jedi.class).invoke("Jump");
+    assertEquals("Jump", Jedi.commonPowerAt(0));
+  }
+
+  @Test
+  public void should_call_static_method_with_no_args_and_no_return_value() {
+    Jedi.addCommonPower("Jump");
+    assertEquals(1, Jedi.commonPowerCount());
+    assertEquals("Jump", Jedi.commonPowerAt(0));
+    StaticMethodName.startStaticMethodAccess("clearCommonPowers").in(Jedi.class).invoke();
+    assertEquals(0, Jedi.commonPowerCount());
+  }
+
+  @Test
+  public void should_throw_error_if_static_method_name_is_invalid() {
+    String message = "Unable to find method 'powerSize' in org.fest.reflect.Jedi with parameter type(s) []";
+    expectReflectionError(message).on(new CodeToTest() {
+      public void run() {
+        String invalidName = "powerSize";
+        StaticMethodName.startStaticMethodAccess(invalidName).in(Jedi.class);
+      }
+    });
+  }
+
+  @Test
+  public void should_throw_error_if_args_for_static_method_are_invalid() {
+    expectIllegalArgumentException("argument type mismatch").on(new CodeToTest() {
+      public void run() {
+        int invalidArg = 8;
+        StaticMethodName.startStaticMethodAccess("addCommonPower").withParameterTypes(String.class).in(Jedi.class)
+            .invoke(invalidArg);
+      }
+    });
+  }
+}
diff --git a/src/test/java/org/fest/reflect/type/Type_Test.java b/src/test/java/org/fest/reflect/type/Type_Test.java
new file mode 100644
index 0000000..05a20e2
--- /dev/null
+++ b/src/test/java/org/fest/reflect/type/Type_Test.java
@@ -0,0 +1,120 @@
+/*
+ * Created on Jan 23, 2009
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2009 the original author or authors.
+ */
+package org.fest.reflect.type;
+
+import static org.fest.reflect.util.ExpectedFailures.expectIllegalArgumentException;
+import static org.fest.reflect.util.ExpectedFailures.expectNullPointerException;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+import org.fest.reflect.Jedi;
+import org.fest.reflect.Person;
+import org.fest.reflect.exception.ReflectionError;
+import org.fest.test.CodeToTest;
+
+/**
+ * Tests for <code>{@link Type}</code>.
+ * 
+ * @author Alex Ruiz
+ */
+public class Type_Test {
+
+  @Test
+  public void should_throw_error_if__type_name_is_null() {
+    expectNullPointerException("The name of the class to load should not be null").on(new CodeToTest() {
+      public void run() {
+        Type.newType(null);
+      }
+    });
+  }
+
+  @Test
+  public void should_throw_error_if__type_name_is_empty() {
+    expectIllegalArgumentException("The name of the class to load should not be empty").on(new CodeToTest() {
+      public void run() {
+        Type.newType("");
+      }
+    });
+  }
+
+  @Test
+  public void should_throw_error_if_subtype_is_mull() {
+    expectNullPointerException("The given type should not be null").on(new CodeToTest() {
+      public void run() {
+        Type.newType("hello").loadAs(null);
+      }
+    });
+  }
+
+  @Test
+  public void should_load_class() {
+    Class<Jedi> expected = Jedi.class;
+    Class<?> type = Type.newType(expected.getName()).load();
+    assertEquals(expected, type);
+  }
+
+  @Test
+  public void should_load_class_with_given_ClassLoader() {
+    Class<Jedi> expected = Jedi.class;
+    Class<?> type = Type.newType(expected.getName()).withClassLoader(getClass().getClassLoader()).load();
+    assertEquals(expected, type);
+  }
+
+  @Test
+  public void should_throw_error_if_Classloader_is_null() {
+    expectNullPointerException("The given class loader should not be null").on(new CodeToTest() {
+      public void run() {
+        Type.newType("hello").withClassLoader(null);
+      }
+    });
+  }
+
+  @Test
+  public void should_wrap_any_Exception_thrown_when_loading_class() {
+    try {
+      Type.newType("org.fest.reflect.NonExistingType").load();
+    } catch (ReflectionError expected) {
+      assertTrue(expected.getMessage().contains("Unable to load class 'org.fest.reflect.NonExistingType' using class loader "));
+      assertTrue(expected.getCause() instanceof ClassNotFoundException);
+    }
+  }
+
+  @Test
+  public void should_load_class_as_given_type() {
+    Class<? extends Person> type = Type.newType(Jedi.class.getName()).loadAs(Person.class);
+    assertEquals(Jedi.class, type);
+  }
+
+  @Test
+  public void should_load_class_as_given_type_with_given_ClassLoader() {
+    Class<? extends Person> type = Type.newType(Jedi.class.getName()).withClassLoader(getClass().getClassLoader())
+        .loadAs(Person.class);
+    assertEquals(Jedi.class, type);
+  }
+
+  @Test
+  public void should_wrap_any_Exception_thrown_when_loading_class_as_given_type() {
+    try {
+      Type.newType("org.fest.reflect.NonExistingType").loadAs(Jedi.class);
+    } catch (ReflectionError expected) {
+      assertTrue(expected.getMessage().contains(
+          "Unable to load class 'org.fest.reflect.NonExistingType' as org.fest.reflect.Jedi using class loader "));
+      assertTrue(expected.getCause() instanceof ClassNotFoundException);
+    }
+  }
+}
diff --git a/src/test/java/org/fest/reflect/util/ExpectedFailures.java b/src/test/java/org/fest/reflect/util/ExpectedFailures.java
new file mode 100644
index 0000000..2f34eeb
--- /dev/null
+++ b/src/test/java/org/fest/reflect/util/ExpectedFailures.java
@@ -0,0 +1,42 @@
+/*
+ * Created on Feb 18, 2008
+ * 
+ * Licensed 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.
+ * 
+ * Copyright @2008-2009 the original author or authors.
+ */
+package org.fest.reflect.util;
+
+import org.fest.reflect.exception.ReflectionError;
+import org.fest.test.ExpectedFailure.Message;
+
+import static org.fest.test.ExpectedFailure.expect;
+
+/**
+ * Understands expected failures.
+ * 
+ * @author Alex Ruiz
+ */
+public final class ExpectedFailures {
+
+  public static Message expectReflectionError(String message) {
+    return expect(ReflectionError.class).withMessage(message);
+  }
+
+  public static Message expectIllegalArgumentException(String message) {
+    return expect(IllegalArgumentException.class).withMessage(message);
+  }
+
+  public static Message expectNullPointerException(String message) {
+    return expect(NullPointerException.class).withMessage(message);
+  }
+
+  private ExpectedFailures() {}
+}

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/fest-reflect.git



More information about the pkg-java-commits mailing list