EMPIREDB-306
previous implmentation did not work as expected and didn't work under Mojarra.
diff --git a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/FacesUtils.java b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/FacesUtils.java
index 50dad0e..e20c6dc 100644
--- a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/FacesUtils.java
+++ b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/FacesUtils.java
@@ -29,6 +29,7 @@
 import javax.faces.application.FacesMessage;

 import javax.faces.component.UIComponent;

 import javax.faces.component.UIInput;

+import javax.faces.component.UIViewRoot;

 import javax.faces.context.ExternalContext;

 import javax.faces.context.FacesContext;

 import javax.servlet.ServletContext;

@@ -41,6 +42,7 @@
 import org.apache.empire.exceptions.EmpireException;

 import org.apache.empire.exceptions.InternalException;

 import org.apache.empire.exceptions.ItemNotFoundException;

+import org.apache.empire.jsf2.impl.FacesImplementation;

 import org.apache.empire.jsf2.pages.Page;

 import org.apache.empire.jsf2.pages.PageDefinition;

 import org.apache.empire.jsf2.pages.PageOutcome;

@@ -62,6 +64,11 @@
         return WebApplication.getInstance();

     }

     

+    public static FacesImplementation getFacesImplementation()

+    {

+        return getWebApplication().getFacesImplementation();    

+    }

+    

     public static FacesContext getContext()

     {

         return FacesContext.getCurrentInstance();

@@ -205,9 +212,14 @@
 

     public static Page getPage(final FacesContext fc)

     {

-        Page page = (Page) getManagedBean(fc, "page");

+        UIViewRoot vr = fc.getViewRoot();

+        if (vr==null)

+            throw new ItemNotFoundException("ViewRoot");

+        // find page

+        Page page = (Page)vr.getViewMap().get("page");

         if (page==null)

-            log.error("Page bean {} does not exist!");

+            throw new ItemNotFoundException("page");

+        // ok

         return page; 

     }

 

diff --git a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/ControlTag.java b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/ControlTag.java
index 7591393..bff104f 100644
--- a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/ControlTag.java
+++ b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/ControlTag.java
@@ -395,6 +395,17 @@
     }

 

     @Override

+    public String getId()

+    {

+        String compId = super.getId();

+        // Mojarra-Patch since Id might have been set to "null"

+        if ("null".equals(compId))

+            compId =  helper.completeInputTagId(null);

+        // done

+        return compId;

+    }

+

+    @Override

     public void processDecodes(FacesContext context) 

     {

         if (helper.isInsideUIData())

diff --git a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/InputTag.java b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/InputTag.java
index 71f6fe2..59fa69e 100644
--- a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/InputTag.java
+++ b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/components/InputTag.java
@@ -30,7 +30,6 @@
 import javax.faces.convert.ConverterException;

 import javax.faces.view.AttachedObjectHandler;

 

-import org.apache.empire.commons.StringUtils;

 import org.apache.empire.data.Column;

 import org.apache.empire.db.DBRecord;

 import org.apache.empire.db.exceptions.FieldIllegalValueException;

@@ -219,6 +218,17 @@
     }

 

     @Override

+    public String getId()

+    {

+        String compId = super.getId();

+        // Mojarra-Patch since Id might have been set to "null"

+        if ("null".equals(compId))

+            compId =  helper.completeInputTagId(null);

+        // done

+        return compId;

+    }

+

+    @Override

     public void processDecodes(FacesContext context) 

     {

         if (helper.isInsideUIData())

diff --git a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/impl/FacesImplementation.java b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/impl/FacesImplementation.java
index 630cb6c..84548f6 100644
--- a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/impl/FacesImplementation.java
+++ b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/impl/FacesImplementation.java
@@ -84,5 +84,12 @@
      *  }

 	 */

 	UIComponent getValueParentComponent(final ValueExpression ve);

+

+	/**

+	 * Returns the inner value expression

+	 * @param ve the original ValueExpression

+	 * @return the unwrapped ValueExpression (may be null)

+	 */

+	ValueExpression unwrapValueExpression(ValueExpression ve);

 	

 }

diff --git a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/impl/MojarraImplementation.java b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/impl/MojarraImplementation.java
index e0a5562..441f5d8 100644
--- a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/impl/MojarraImplementation.java
+++ b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/impl/MojarraImplementation.java
@@ -18,27 +18,36 @@
  */

 package org.apache.empire.jsf2.impl;

 

-import java.util.Map;

-

 import javax.el.ValueExpression;

+import javax.el.VariableMapper;

 import javax.faces.component.UIComponent;

 import javax.faces.context.FacesContext;

 

+import org.apache.empire.commons.ObjectUtils;

+import org.apache.empire.commons.StringUtils;

 import org.apache.empire.exceptions.ItemExistsException;

-import org.apache.empire.jsf2.app.WebApplication;

+import org.slf4j.Logger;

+import org.slf4j.LoggerFactory;

 

 import com.sun.faces.application.ApplicationAssociate;

-import com.sun.faces.application.ApplicationFactoryImpl;

-import com.sun.faces.application.InjectionApplicationFactory;

 import com.sun.faces.component.CompositeComponentStackManager;

 import com.sun.faces.facelets.el.ContextualCompositeValueExpression;

+import com.sun.faces.facelets.el.TagValueExpression;

 import com.sun.faces.mgbean.BeanManager;

 import com.sun.faces.mgbean.ManagedBeanInfo;

 

 public class MojarraImplementation implements FacesImplementation 

 {

-	private BeanManager bm;

+    // Logger

+    private static final Logger log = LoggerFactory.getLogger(FacesImplementation.class);

 

+    private BeanManager bm;

+    

+    public MojarraImplementation()

+	{

+	    log.debug("MojarraImplementation created");

+	}

+		

 	/*

 	@Override

 	public void initApplication(final FacesApplication application)

@@ -71,7 +80,7 @@
 	@Override

 	public Object getManagedBean(final String beanName, final FacesContext fc)

 	{

-		// Find Bean

+	    // Find Bean

 	    if (bm==null)

             bm = ApplicationAssociate.getInstance(fc.getExternalContext()).getBeanManager();

 		Object mbean = bm.getBeanFromScope(beanName, fc);

@@ -95,4 +104,49 @@
         return null;

 	}

 

+    @Override

+    public ValueExpression unwrapValueExpression(ValueExpression ve)

+    {

+        // unwrap from com.sun.faces.facelets.el.TagValueExpression

+        if (ve instanceof TagValueExpression)

+        {   // cast and getWrapped

+            ve = ((TagValueExpression)ve).getWrapped();

+        }

+        // now unwrap ValueExpressionImpl

+        if (ve!=null)

+        {   // expected: ve = org.apache.el.ValueExpressionImpl

+            if (ve.getClass().getName().equals("org.apache.el.ValueExpressionImpl"))

+            {   // get the Node

+                Object node = ObjectUtils.invokeSimplePrivateMethod(ve, "getNode");

+                if (node!=null)

+                {   // we have a Node

+                    // now get the Image

+                    String image = StringUtils.toString(ObjectUtils.invokeSimpleMethod(node, "getImage"));

+                    if (StringUtils.isNotEmpty(image)) 

+                    {   // find the varMapper

+                        Object varMapper = ObjectUtils.getPrivateFieldValue(ve, "varMapper");

+                        if (varMapper!=null)

+                        {   // Resolve variable using mapper

+                            log.debug("Resolving el-variable \"{}\" using VariableMapper", image);

+                            VariableMapper vm = (VariableMapper)varMapper;

+                            ve = vm.resolveVariable(image);

+                        } else {

+                            // Variable not provided!

+                            ve = null;

+                        }

+                    } else {

+                        // no image: unwrapping not necessary

+                        // use original ValueExpression!

+                    }

+                }

+            } else {

+                // unexpected

+                log.warn("Unexpected ValueExpression-Implementation: {}", ve.getClass().getName());

+                log.warn("ValueExpression unwrapping does not work!");

+            }

+        }

+        // done 

+        return ve;

+    }

+	

 }

diff --git a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/impl/MyFacesImplementation.java b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/impl/MyFacesImplementation.java
index 2b60a52..be00d29 100644
--- a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/impl/MyFacesImplementation.java
+++ b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/impl/MyFacesImplementation.java
@@ -20,16 +20,30 @@
 

 import javax.el.ELContext;

 import javax.el.ValueExpression;

+import javax.el.VariableMapper;

 import javax.faces.application.Application;

 import javax.faces.component.UIComponent;

 import javax.faces.context.FacesContext;

 

+import org.apache.empire.commons.ObjectUtils;

+import org.apache.empire.commons.StringUtils;

 import org.apache.empire.exceptions.ItemExistsException;

 import org.apache.myfaces.config.RuntimeConfig;

 import org.apache.myfaces.config.impl.digester.elements.ManagedBeanImpl;

+import org.apache.myfaces.view.facelets.el.ContextAwareTagValueExpression;

+import org.slf4j.Logger;

+import org.slf4j.LoggerFactory;

 

 public class MyFacesImplementation implements FacesImplementation 

 {

+    // Logger

+    private static final Logger log = LoggerFactory.getLogger(FacesImplementation.class);

+

+    public MyFacesImplementation()

+    {

+        log.debug("MyFacesImplementation created");

+    }

+    

     /*

 	@Override

 	public void initApplication(FacesApplication application)

@@ -77,4 +91,49 @@
 		return null;

 	}

 

+    @Override

+    public ValueExpression unwrapValueExpression(ValueExpression ve)

+    {

+        // unwrap from org.apache.myfaces.view.facelets.el.ContextAwareTagValueExpression

+        if (ve instanceof ContextAwareTagValueExpression)

+        {   // cast and getWrapped

+            ve = ((ContextAwareTagValueExpression)ve).getWrapped();

+        }

+        // now unwrap ValueExpressionImpl

+        if (ve!=null)

+        {   // expected: ve = org.apache.el.ValueExpressionImpl

+            if (ve.getClass().getName().equals("org.apache.el.ValueExpressionImpl"))

+            {   // get the Node

+                Object node = ObjectUtils.invokeSimplePrivateMethod(ve, "getNode");

+                if (node!=null)

+                {   // we have a Node

+                    // now get the Image

+                    String image = StringUtils.toString(ObjectUtils.invokeSimpleMethod(node, "getImage"));

+                    if (StringUtils.isNotEmpty(image)) 

+                    {   // find the varMapper

+                        Object varMapper = ObjectUtils.getPrivateFieldValue(ve, "varMapper");

+                        if (varMapper!=null)

+                        {   // Resolve variable using mapper

+                            log.debug("Resolving el-variable \"{}\" using VariableMapper", image);

+                            VariableMapper vm = (VariableMapper)varMapper;

+                            ve = vm.resolveVariable(image);

+                        } else {

+                            // Variable not provided!

+                            ve = null;

+                        }

+                    } else {

+                        // no image: unwrapping not necessary

+                        // use original ValueExpression!

+                    }

+                }

+            } else {

+                // unexpected

+                log.warn("Unexpected ValueExpression-Implementation: {}", ve.getClass().getName());

+                log.warn("ValueExpression unwrapping does not work!");

+            }

+        }

+        // done 

+        return ve;

+    }

+

 }

diff --git a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/utils/TagEncodingHelper.java b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/utils/TagEncodingHelper.java
index e61712c..b5683a9 100644
--- a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/utils/TagEncodingHelper.java
+++ b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/utils/TagEncodingHelper.java
@@ -23,9 +23,7 @@
 import java.util.Iterator;

 import java.util.Locale;

 

-import javax.el.ELContext;

 import javax.el.ValueExpression;

-import javax.el.ValueReference;

 import javax.faces.FacesWrapper;

 import javax.faces.application.FacesMessage;

 import javax.faces.component.NamingContainer;

@@ -203,7 +201,7 @@
         /* Value Options */

         protected boolean hasColumn()

         {

-            return (column != null || getColumn() != null);

+            return (column != null || TagEncodingHelper.this.hasColumn());

         }

 

         @Override

@@ -404,7 +402,7 @@
     protected RecordTag           recordTag    = null;

     protected UIData              uiDataTag    = null;

     // protected Boolean          tagRequired  = null;

-    protected Boolean             hasValueRef  = null;

+    protected Boolean             hasValueExpr = null;

     protected InputControl        control      = null;

     protected TextResolver        textResolver = null;

     protected Object              mostRecentValue = null;

@@ -455,11 +453,12 @@
         else if (id.indexOf(PH_COLUMN_FULL)>=0) 

         {   // column full name including table

             String name= null;

-            Column c = getColumn();

-            if (c instanceof DBColumn)

-                name = ((DBColumn)c).getFullName().replace('.', '_');

-            else if (c!=null)

-                name = c.getName();

+            if (column==null)

+                column = findColumn();

+            if (column instanceof DBColumn)

+                name = ((DBColumn)column).getFullName().replace('.', '_');

+            else if (column!=null)

+                name = column.getName();

             id = id.replace(PH_COLUMN_FULL, String.valueOf(name));

         }

         // done 

@@ -602,21 +601,29 @@
     {

         if (column == null)

             column = findColumn();

+        if (column == null)

+        {   // @deprecated: for compatiblity only!

+            column = findColumnFromValue();  

+            if (column!=null)

+                log.warn("Providing the column as the value is deprecated. Use column attribute insteam. This might be removed in future versions!");

+        }

         return (column != null);

     }

 

     public Column getColumn()

     {

-        if (column == null)

-            column = findColumn();

-        if (column == null)

+        if (hasColumn())

+            return this.column;

+        else

             throw new InvalidArgumentException("column", column);

-        return column;

     }

     

     public String getColumnName()

     {

-        return ((this.column=findColumn())!=null ? column.getName() : "null");

+        // don't use hasColumn() or getColumn() here!

+        if (column==null)

+            column = findColumn(); 

+        return (column!=null ? column.getName() : "null");

     }

 

     public void setColumn(Column column)

@@ -792,7 +799,7 @@
             if (!(record instanceof Record) || ((Record) record).isReadOnly())

                 return true;

         }

-        else if (!hasValueReference())

+        else if (!hasValueExpression())

         { // No Value expression given

             return true;

         }

@@ -850,7 +857,7 @@
             return r.isFieldRequired(getColumn());

         }

         // Check Value Attribute

-        if (hasValueReference())

+        if (hasValueExpression())

             return false;

         // Required

         return getColumn().isRequired();

@@ -918,34 +925,39 @@
             // done

             return column;

         }

-        // When null, try value

-        if (col == null)

-        { // Try value

-            col = component.getValue();

-            // Column supplied?

-            if (col instanceof Column)

-            {

-                return (Column) col;

-            }

-            // Column expression supplied?

-            if (col instanceof ColumnExpr)

-            { // Use source column instead 

-                Column source = ((ColumnExpr) col).getSourceColumn();

-                if (source != null)

-                    return source;

-                // No source column? --> wrap 

-                return createColumnExprWrapper((ColumnExpr) col);

-            }

-        }

         // No column!

         if (log.isDebugEnabled() && !(component instanceof LinkTag))

             log.warn("No Column provided for value tag!");

         return null;

     }

+

+    /**

+     * Checks whether the value attribute contains a column reference and returns it

+     * @return the column

+     */

+    protected Column findColumnFromValue()

+    {   // Try value

+        Object col = component.getValue();

+        // Column supplied?

+        if (col instanceof Column)

+        {

+            return (Column) col;

+        }

+        // Column expression supplied?

+        if (col instanceof ColumnExpr)

+        { // Use source column instead 

+            Column source = ((ColumnExpr) col).getSourceColumn();

+            if (source != null)

+                return source;

+            // No source column? --> wrap 

+            return createColumnExprWrapper((ColumnExpr) col);

+        }

+        return null;

+    }

     

     protected Column createColumnExprWrapper(ColumnExpr colExpr)

     {

-         return new ColumnExprWrapper(colExpr);

+        return new ColumnExprWrapper(colExpr);

     }

     

     protected ColumnExpr unwrapColumnExpr(Column col)

@@ -961,7 +973,7 @@
         if (rec != null)

             return rec;

         // Value expression

-        if (hasValueReference())

+        if (hasValueExpression())

         {   // See if the record is in value

             return null;

         }       

@@ -970,39 +982,36 @@
         if (rec==null)

         {   // not supplied

             if ((component instanceof ControlTag) && !((ControlTag)component).isCustomInput())

-                log.warn("No record supplied for {} and column {}.", component.getClass().getSimpleName(), getColumnName());

+                log.warn("No record supplied for {} and column {}.", component.getClass().getSimpleName(), getColumnName()); 

         }

         return rec;

     }

     

-    protected boolean hasValueReference()

+    protected boolean hasValueExpression()

     {

         // Find expression

-        if (hasValueRef != null)

-            return hasValueRef.booleanValue();

+        if (hasValueExpr != null)

+            return hasValueExpr.booleanValue();

         // Find expression

-        boolean hasVR = false;

         ValueExpression ve = findValueExpression("value", false);

         if (ve != null)

-        {   // check

-            ELContext elc = FacesContext.getCurrentInstance().getELContext();

-            ValueReference vr = ve.getValueReference(elc);

-            if (vr!=null && log.isDebugEnabled())  

-            {   // log value reference

-                Object base = vr.getBase();

-                Object property = vr.getProperty();

-                String writeable = (ve.isReadOnly(elc) ? "read-only" : "updateable");

-                String beanName = (base!=null ? base.getClass().getSimpleName() : "{NULL}");

-                log.debug("Tag-ValueExpression for {} on {}.{} is {}. Expression is \"{}\".", getColumnName(), beanName, property, writeable, ve.getExpressionString());

+        {   // We have a ValueExpression!

+            // Now unwrap for Facelet-Tags to work

+            String originalExpr = ve.getExpressionString(); // log.isDebugEnabled() ? ve.getExpressionString() : null;

+            ve = FacesUtils.getFacesImplementation().unwrapValueExpression(ve);

+            if (originalExpr!=null)

+            {   // log result

+                if (ve!=null)

+                    log.info("ValueExpression \"{}\" has been resolved to \"{}\" from class {}", originalExpr, ve.getExpressionString(), ve.getClass().getName());

+                else 

+                    log.info("ValueExpression \"{}\" has been resolved to NULL", originalExpr);

             }

-            // set result

-            hasVR = (vr!=null);

         }

         // store result to avoid multiple detection 

-        hasValueRef = Boolean.valueOf(hasVR);

-        return hasValueRef.booleanValue();

+        hasValueExpr = Boolean.valueOf(ve!=null);

+        return hasValueExpr.booleanValue();

     }

-    

+        

     protected static final String CC_ATTR_EXPR = "#{cc.attrs.";

     

     @SuppressWarnings("unchecked")

@@ -1021,7 +1030,7 @@
             if (ve instanceof FacesWrapper<?>)

                 ve = ((FacesWrapper<ValueExpression>)ve).getWrapped();

             // find parent

-            UIComponent valueParent = FacesUtils.getWebApplication().getFacesImplementation().getValueParentComponent(ve);

+            UIComponent valueParent = FacesUtils.getFacesImplementation().getValueParentComponent(ve);

             if (valueParent!=null)

             {	// use the value parent

             	parent = valueParent;

diff --git a/empire-db/src/main/java/org/apache/empire/commons/ObjectUtils.java b/empire-db/src/main/java/org/apache/empire/commons/ObjectUtils.java
index 8884c3a..8a6a3c8 100644
--- a/empire-db/src/main/java/org/apache/empire/commons/ObjectUtils.java
+++ b/empire-db/src/main/java/org/apache/empire/commons/ObjectUtils.java
@@ -19,6 +19,9 @@
 package org.apache.empire.commons;
 
 import java.io.Serializable;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.text.SimpleDateFormat;
@@ -29,6 +32,10 @@
 import java.util.Locale;
 
 import org.apache.commons.beanutils.MethodUtils;
+import org.apache.empire.exceptions.EmpireException;
+import org.apache.empire.exceptions.InternalException;
+import org.apache.empire.exceptions.InvalidArgumentException;
+import org.apache.empire.exceptions.NotSupportedException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -653,5 +660,180 @@
         }
         return false;
     }
+
+    /**
+     * Retrieve a field value using reflection
+     * @param clazz the class from which to obtain the field
+     * @param object the object instance from which to obtain the field
+     * @param property the property to obtain 
+     * @param includePrivateFields flag whether or not to include private fields
+     * @return the property value
+     */
+    public static synchronized Object getFieldValue(Class<?> clazz, Object object, String property, boolean includePrivateFields)
+    {
+        // check arguments
+        if (object==null)
+            throw new InvalidArgumentException("object", object);
+        if (clazz==null || !clazz.isInstance(object))
+            throw new InvalidArgumentException("clazz", clazz);
+        if (StringUtils.isEmpty(property))
+            throw new InvalidArgumentException("property", property);
+        // begin
+        boolean accessible = true; 
+        Field field = null;
+        try
+        { // find and invoke
+            field = (includePrivateFields ? clazz.getDeclaredField(property) : clazz.getField(property));
+            accessible = field.isAccessible();
+            if (includePrivateFields && accessible==false)
+                field.setAccessible(true);
+            // invoke
+            return field.get(object);
+        }
+        catch (NoSuchFieldException e)
+        {   // No such Method
+            if (includePrivateFields)
+            {   // try superclass
+                clazz = clazz.getSuperclass();
+                if (clazz!=null && !clazz.equals(java.lang.Object.class))
+                    return getFieldValue(clazz, object, property, true);
+            }
+            // not found
+            return null;
+        }
+        catch (IllegalAccessException e)
+        {   // Invalid Method definition   
+            throw new NotSupportedException(object, property, e);
+        }
+        finally {
+            // restore accessible
+            if (field!=null && accessible==false)
+                field.setAccessible(false);
+        }
+    }
+
+    /**
+     * Retrieve a field value using reflection
+     * The field accessor must be public
+     * @param object the object instance from which to obtain the field
+     * @param property the property to obtain 
+     * @return the property value
+     */
+    public static Object getFieldValue(Object object, String property)
+    {
+        if (object==null)
+            throw new InvalidArgumentException("object", object);
+        // begin
+        return getFieldValue(object.getClass(), object, property, false);
+    }
+
+    /**
+     * Retrieve a field value using reflection 
+     * @param object the object instance from which to obtain the field
+     * @param property the property to obatin 
+     * @return the property value
+     */
+    public static Object getPrivateFieldValue(Object object, String property)
+    {
+        if (object==null)
+            throw new InvalidArgumentException("object", object);
+        // begin
+        return getFieldValue(object.getClass(), object, property, true);
+    }
+    
+    /**
+     * Invoke a simple method (without parameters) on an object using reflection
+     * @param clazz the class from which to obtain the field
+     * @param object the object instance on which to invoke the method
+     * @param methodName the name of the method to invoke 
+     * @param includePrivateMethods flag whether or not to include private methods
+     * @return the return value of the method
+     */
+    public static synchronized Object invokeSimpleMethod(Class<?> clazz, Object object, String methodName, boolean includePrivateMethods)
+    {
+        // check arguments
+        if (object==null)
+            throw new InvalidArgumentException("object", object);
+        if (clazz==null || !clazz.isInstance(object))
+            throw new InvalidArgumentException("clazz", clazz);
+        if (StringUtils.isEmpty(methodName))
+            throw new InvalidArgumentException("methodName", methodName);
+        // begin
+        boolean accessible = true; 
+        Method method = null;
+        try
+        { // find and invoke
+            method = (includePrivateMethods ? clazz.getDeclaredMethod(methodName) : clazz.getMethod(methodName));
+            accessible = method.isAccessible();
+            if (includePrivateMethods && accessible==false)
+                method.setAccessible(true);
+            // invoke
+            return method.invoke(object);
+        }
+        catch (NoSuchMethodException e)
+        {   // No such Method
+            if (includePrivateMethods)
+            {   // try superclass
+                clazz = clazz.getSuperclass();
+                if (clazz!=null && !clazz.equals(java.lang.Object.class))
+                    return invokeSimpleMethod(clazz, object, methodName, true);
+            }
+            // not found
+            return null;
+        }
+        catch (SecurityException e)
+        {   // Invalid Method definition   
+            throw new NotSupportedException(object, methodName, e);
+        }
+        catch (IllegalAccessException e)
+        {   // Invalid Method definition   
+            throw new NotSupportedException(object, methodName, e);
+        }
+        catch (IllegalArgumentException e)
+        {   // Invalid Method definition   
+            throw new NotSupportedException(object, methodName, e);
+        }
+        catch (InvocationTargetException e)
+        {   // Error inside Method
+            Throwable cause = e.getCause();
+            if (cause instanceof EmpireException)
+                throw (EmpireException)cause;
+            // wrap    
+            throw new InternalException(cause);
+        }
+        finally {
+            // restore accessible
+            if (method!=null && accessible==false)
+                method.setAccessible(false);
+        }
+    }
+
+    /**
+     * Invoke a simple method (without parameters) on an object using reflection
+     * @param object the object instance on which to invoke the method
+     * @param methodName the name of the method to invoke 
+     * @return the return value of the method
+     */
+    public static Object invokeSimpleMethod(Object object, String methodName)
+    {
+        if (object==null)
+            throw new InvalidArgumentException("object", object);
+        // begin
+        return invokeSimpleMethod(object.getClass(), object, methodName, false);
+    }
+
+    /**
+     * Invoke a simple method (without parameters) on an object using reflection
+     * @param object the object instance on which to invoke the method
+     * @param methodName the name of the method to invoke 
+     * @return the return value of the method
+     */
+    public static Object invokeSimplePrivateMethod(Object object, String methodName)
+    {
+        if (object==null)
+            throw new InvalidArgumentException("object", object);
+        // begin
+        return invokeSimpleMethod(object.getClass(), object, methodName, true);
+    }
     
 }
diff --git a/pom.xml b/pom.xml
index 810058c..3ace06c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -352,12 +352,12 @@
 			<dependency>

 				<groupId>com.sun.faces</groupId>

 				<artifactId>jsf-api</artifactId>

-				<version>2.2.15</version>

+				<version>2.2.20</version>

 			</dependency>

 			<dependency>

 				<groupId>com.sun.faces</groupId>

 				<artifactId>jsf-impl</artifactId>

-				<version>2.2.15</version>

+				<version>2.2.20</version>

 			</dependency>

 			<!-- Apache MyFaces -->

 			<dependency>