You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by th...@apache.org on 2014/12/21 20:56:29 UTC

[03/35] tapestry-5 git commit: First pass creating the BeanModel and Commons packages. Lots of stuff moved around, but no actual code changes so far

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/f963c7ab/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PropertyConduitSourceImpl.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PropertyConduitSourceImpl.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PropertyConduitSourceImpl.java
deleted file mode 100644
index 701420f..0000000
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PropertyConduitSourceImpl.java
+++ /dev/null
@@ -1,1563 +0,0 @@
-// Copyright 2007-2013 The Apache Software Foundation
-//
-// 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.
-
-package org.apache.tapestry5.internal.services;
-
-import org.antlr.runtime.ANTLRInputStream;
-import org.antlr.runtime.CommonTokenStream;
-import org.antlr.runtime.tree.Tree;
-import org.apache.tapestry5.PropertyConduit;
-import org.apache.tapestry5.PropertyConduit2;
-import org.apache.tapestry5.internal.InternalPropertyConduit;
-import org.apache.tapestry5.internal.antlr.PropertyExpressionLexer;
-import org.apache.tapestry5.internal.antlr.PropertyExpressionParser;
-import org.apache.tapestry5.internal.util.IntegerRange;
-import org.apache.tapestry5.internal.util.MultiKey;
-import org.apache.tapestry5.ioc.AnnotationProvider;
-import org.apache.tapestry5.ioc.annotations.PostInjection;
-import org.apache.tapestry5.ioc.internal.NullAnnotationProvider;
-import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
-import org.apache.tapestry5.ioc.internal.util.GenericsUtils;
-import org.apache.tapestry5.ioc.internal.util.InternalUtils;
-import org.apache.tapestry5.ioc.services.*;
-import org.apache.tapestry5.ioc.util.AvailableValues;
-import org.apache.tapestry5.ioc.util.ExceptionUtils;
-import org.apache.tapestry5.ioc.util.UnknownValueException;
-import org.apache.tapestry5.plastic.*;
-import org.apache.tapestry5.services.ComponentClasses;
-import org.apache.tapestry5.services.ComponentLayer;
-import org.apache.tapestry5.services.InvalidationEventHub;
-import org.apache.tapestry5.services.PropertyConduitSource;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.*;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import static org.apache.tapestry5.internal.antlr.PropertyExpressionParser.*;
-
-public class PropertyConduitSourceImpl implements PropertyConduitSource
-{
-    static class ConduitMethods
-    {
-        private static final MethodDescription GET = getMethodDescription(PropertyConduit.class, "get", Object.class);
-
-        private static final MethodDescription SET = getMethodDescription(PropertyConduit.class, "set", Object.class,
-                Object.class);
-
-        private static final MethodDescription GET_PROPERTY_TYPE = getMethodDescription(PropertyConduit.class,
-                "getPropertyType");
-
-        private static final MethodDescription GET_PROPERTY_GENERIC_TYPE = getMethodDescription(PropertyConduit2.class,
-                "getPropertyGenericType");
-        
-        private static final MethodDescription GET_PROPERTY_NAME = getMethodDescription(InternalPropertyConduit.class,
-                "getPropertyName");
-        
-        private static final MethodDescription GET_ANNOTATION = getMethodDescription(AnnotationProvider.class,
-                "getAnnotation", Class.class);
-
-    }
-
-    static class DelegateMethods
-    {
-        static final Method INVERT = getMethod(PropertyConduitDelegate.class, "invert", Object.class);
-
-        static final Method RANGE = getMethod(PropertyConduitDelegate.class, "range", int.class, int.class);
-
-        static final Method COERCE = getMethod(PropertyConduitDelegate.class, "coerce", Object.class, Class.class);
-    }
-
-    static class ArrayListMethods
-    {
-        static final Method ADD = getMethod(ArrayList.class, "add", Object.class);
-    }
-
-    static class HashMapMethods
-    {
-        static final Method PUT = getMethod(HashMap.class, "put", Object.class, Object.class);
-    }
-
-    private static InstructionBuilderCallback RETURN_NULL = new InstructionBuilderCallback()
-    {
-        public void doBuild(InstructionBuilder builder)
-        {
-            builder.loadNull().returnResult();
-        }
-    };
-
-    private static final String[] SINGLE_OBJECT_ARGUMENT = new String[]
-            {Object.class.getName()};
-
-    @SuppressWarnings("unchecked")
-    private static Method getMethod(Class containingClass, String name, Class... parameterTypes)
-    {
-        try
-        {
-            return containingClass.getMethod(name, parameterTypes);
-        } catch (NoSuchMethodException ex)
-        {
-            throw new IllegalArgumentException(ex);
-        }
-    }
-
-    private static MethodDescription getMethodDescription(Class containingClass, String name, Class... parameterTypes)
-    {
-        return new MethodDescription(getMethod(containingClass, name, parameterTypes));
-    }
-
-    private final AnnotationProvider nullAnnotationProvider = new NullAnnotationProvider();
-
-    /**
-     * How are null values in intermdiate terms to be handled?
-     */
-    private enum NullHandling
-    {
-        /**
-         * Add code to check for null and throw exception if null.
-         */
-        FORBID,
-
-        /**
-         * Add code to check for null and short-circuit (i.e., the "?."
-         * safe-dereference operator)
-         */
-        ALLOW
-    }
-
-    /**
-     * One term in an expression. Expressions start with some root type and each term advances
-     * to a new type.
-     */
-    private class Term
-    {
-        /**
-         * The generic type of the term.
-         */
-        final Type type;
-
-        final Class genericType;
-
-        /**
-         * Describes the term, for use in error messages.
-         */
-        final String description;
-
-        final AnnotationProvider annotationProvider;
-
-        /**
-         * Callback that will implement the term.
-         */
-        final InstructionBuilderCallback callback;
-
-        Term(Type type, Class genericType, String description, AnnotationProvider annotationProvider,
-             InstructionBuilderCallback callback)
-        {
-            this.type = type;
-            this.genericType = genericType;
-            this.description = description;
-            this.annotationProvider = annotationProvider;
-            this.callback = callback;
-        }
-
-        Term(Type type, String description, AnnotationProvider annotationProvider, InstructionBuilderCallback callback)
-        {
-            this(type, GenericsUtils.asClass(type), description, annotationProvider, callback);
-        }
-
-        Term(Type type, String description, InstructionBuilderCallback callback)
-        {
-            this(type, description, null, callback);
-        }
-
-        /**
-         * Returns a clone of this Term with a new callback.
-         */
-        Term withCallback(InstructionBuilderCallback newCallback)
-        {
-            return new Term(type, genericType, description, annotationProvider, newCallback);
-        }
-    }
-
-    private final PropertyAccess access;
-
-    private final PlasticProxyFactory proxyFactory;
-
-    private final TypeCoercer typeCoercer;
-
-    private final StringInterner interner;
-
-    /**
-     * Keyed on combination of root class and expression.
-     */
-    private final Map<MultiKey, PropertyConduit> cache = CollectionFactory.newConcurrentMap();
-
-    private final Invariant invariantAnnotation = new Invariant()
-    {
-        public Class<? extends Annotation> annotationType()
-        {
-            return Invariant.class;
-        }
-    };
-
-    private final AnnotationProvider invariantAnnotationProvider = new AnnotationProvider()
-    {
-        public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
-        {
-            if (annotationClass == Invariant.class)
-                return annotationClass.cast(invariantAnnotation);
-
-            return null;
-        }
-    };
-
-    private final PropertyConduit literalTrue;
-
-    private final PropertyConduit literalFalse;
-
-    private final PropertyConduit literalNull;
-
-    private final PropertyConduitDelegate sharedDelegate;
-
-    /**
-     * Encapsulates the process of building a PropertyConduit instance from an
-     * expression, as an {@link PlasticClassTransformer}.
-     */
-    class PropertyConduitBuilder implements PlasticClassTransformer
-    {
-        private final Class rootType;
-
-        private final String expression;
-
-        private final Tree tree;
-
-        private Class conduitPropertyType;
-
-        private Type conduitPropertyGenericType;
-
-        private String conduitPropertyName;
-
-        private AnnotationProvider annotationProvider = nullAnnotationProvider;
-
-        private PlasticField delegateField;
-
-        private PlasticClass plasticClass;
-
-        private PlasticMethod getRootMethod, navMethod;
-
-        PropertyConduitBuilder(Class rootType, String expression, Tree tree)
-        {
-            this.rootType = rootType;
-            this.expression = expression;
-            this.tree = tree;
-        }
-
-        public void transform(PlasticClass plasticClass)
-        {
-            this.plasticClass = plasticClass;
-
-            // Create the various methods; also determine the conduit's property type, property name and identify
-            // the annotation provider.
-
-            implementNavMethodAndAccessors();
-
-            implementOtherMethods();
-
-            plasticClass.addToString(String.format("PropertyConduit[%s %s]", rootType.getName(), expression));
-        }
-
-        private void implementOtherMethods()
-        {
-            PlasticField annotationProviderField = plasticClass.introduceField(AnnotationProvider.class,
-                    "annotationProvider").inject(annotationProvider);
-
-            plasticClass.introduceMethod(ConduitMethods.GET_ANNOTATION).delegateTo(annotationProviderField);
-
-            plasticClass.introduceMethod(ConduitMethods.GET_PROPERTY_NAME, new InstructionBuilderCallback()
-            {
-                public void doBuild(InstructionBuilder builder)
-                {
-                    builder.loadConstant(conduitPropertyName).returnResult();
-                }
-            });
-
-            final PlasticField propertyTypeField = plasticClass.introduceField(Class.class, "propertyType").inject(
-                    conduitPropertyType);
-
-            plasticClass.introduceMethod(ConduitMethods.GET_PROPERTY_TYPE, new InstructionBuilderCallback()
-            {
-                public void doBuild(InstructionBuilder builder)
-                {
-                    builder.loadThis().getField(propertyTypeField).returnResult();
-                }
-            });
-
-            final PlasticField propertyGenericTypeField = plasticClass.introduceField(Type.class, "propertyGenericType").inject(
-                    conduitPropertyGenericType);
-
-            plasticClass.introduceMethod(ConduitMethods.GET_PROPERTY_GENERIC_TYPE, new InstructionBuilderCallback()
-            {
-                public void doBuild(InstructionBuilder builder)
-                {
-                    builder.loadThis().getField(propertyGenericTypeField).returnResult();
-                }
-            });
-        }
-
-        /**
-         * Creates a method that does a conversion from Object to the expected root type, with
-         * a null check.
-         */
-        private void implementGetRoot()
-        {
-            getRootMethod = plasticClass.introducePrivateMethod(PlasticUtils.toTypeName(rootType), "getRoot",
-                    SINGLE_OBJECT_ARGUMENT, null);
-
-            getRootMethod.changeImplementation(new InstructionBuilderCallback()
-            {
-                public void doBuild(InstructionBuilder builder)
-                {
-                    builder.loadArgument(0).dupe().when(Condition.NULL, new InstructionBuilderCallback()
-                    {
-                        public void doBuild(InstructionBuilder builder)
-                        {
-                            builder.throwException(NullPointerException.class,
-                                    String.format("Root object of property expression '%s' is null.", expression));
-                        }
-                    });
-
-                    builder.checkcast(rootType).returnResult();
-                }
-            });
-        }
-
-        private boolean isLeaf(Tree node)
-        {
-            int type = node.getType();
-
-            return type != DEREF && type != SAFEDEREF;
-        }
-
-        private void implementNavMethodAndAccessors()
-        {
-            implementGetRoot();
-
-            // First, create the navigate method.
-
-            final List<InstructionBuilderCallback> callbacks = CollectionFactory.newList();
-
-            Type activeType = rootType;
-
-            Tree node = tree;
-
-            while (!isLeaf(node))
-            {
-                Term term = analyzeDerefNode(activeType, node);
-
-                callbacks.add(term.callback);
-
-                activeType = term.type;
-
-                // Second term is the continuation, possibly another chained
-                // DEREF, etc.
-                node = node.getChild(1);
-            }
-
-            Class activeClass = GenericsUtils.asClass(activeType);
-
-            if (callbacks.isEmpty())
-            {
-                navMethod = getRootMethod;
-            } else
-            {
-                navMethod = plasticClass.introducePrivateMethod(PlasticUtils.toTypeName(activeClass), "navigate",
-                        SINGLE_OBJECT_ARGUMENT, null);
-
-                navMethod.changeImplementation(new InstructionBuilderCallback()
-                {
-                    public void doBuild(InstructionBuilder builder)
-                    {
-                        builder.loadThis().loadArgument(0).invokeVirtual(getRootMethod);
-
-                        for (InstructionBuilderCallback callback : callbacks)
-                        {
-                            callback.doBuild(builder);
-                        }
-
-                        builder.returnResult();
-                    }
-                });
-            }
-
-            implementAccessors(activeType, node);
-        }
-
-        private void implementAccessors(Type activeType, Tree node)
-        {
-            switch (node.getType())
-            {
-                case IDENTIFIER:
-
-                    implementPropertyAccessors(activeType, node);
-
-                    return;
-
-                case INVOKE:
-
-                    // So, at this point, we have the navigation method written
-                    // and it covers all but the terminal
-                    // de-reference. node is an IDENTIFIER or INVOKE. We're
-                    // ready to use the navigation
-                    // method to implement get() and set().
-
-                    implementMethodAccessors(activeType, node);
-
-                    return;
-
-                case RANGEOP:
-
-                    // As currently implemented, RANGEOP can only appear as the
-                    // top level, which
-                    // means we didn't need the navigate method after all.
-
-                    implementRangeOpGetter(node);
-                    implementNoOpSetter();
-
-                    conduitPropertyType = IntegerRange.class;
-                    conduitPropertyGenericType = IntegerRange.class;
-
-                    return;
-
-                case LIST:
-
-                    implementListGetter(node);
-                    implementNoOpSetter();
-
-                    conduitPropertyType = List.class;
-                    conduitPropertyGenericType = List.class;
-                    
-                    return;
-
-                case MAP:
-                    implementMapGetter(node);
-                    implementNoOpSetter();
-
-                    conduitPropertyType = Map.class;
-                    conduitPropertyGenericType = Map.class;
-
-                    return;
-
-
-                case NOT:
-                    implementNotOpGetter(node);
-                    implementNoOpSetter();
-
-                    conduitPropertyType = boolean.class;
-                    conduitPropertyGenericType = boolean.class;
-
-                    return;
-
-                default:
-                    throw unexpectedNodeType(node, IDENTIFIER, INVOKE, RANGEOP, LIST, NOT);
-            }
-        }
-
-        public void implementMethodAccessors(final Type activeType, final Tree invokeNode)
-        {
-            final Term term = buildInvokeTerm(activeType, invokeNode);
-
-            implementNoOpSetter();
-
-            conduitPropertyName = term.description;
-            conduitPropertyType = term.genericType;
-            conduitPropertyGenericType = term.genericType;
-            annotationProvider = term.annotationProvider;
-
-            plasticClass.introduceMethod(ConduitMethods.GET, new InstructionBuilderCallback()
-            {
-                public void doBuild(InstructionBuilder builder)
-                {
-                    invokeNavigateMethod(builder);
-
-                    term.callback.doBuild(builder);
-
-                    boxIfPrimitive(builder, conduitPropertyType);
-
-                    builder.returnResult();
-                }
-            });
-
-            implementNoOpSetter();
-        }
-
-        public void implementPropertyAccessors(Type activeType, Tree identifierNode)
-        {
-            String propertyName = identifierNode.getText();
-
-            PropertyAdapter adapter = findPropertyAdapter(activeType, propertyName);
-
-            conduitPropertyName = propertyName;
-            conduitPropertyType = adapter.getType();
-            conduitPropertyGenericType = getGenericType(adapter);
-            annotationProvider = adapter;
-
-            implementGetter(adapter);
-            implementSetter(adapter);
-        }
-
-        private Type getGenericType(PropertyAdapter adapter)
-        {
-        	Type genericType = null;
-        	if (adapter.getField() != null)
-        	{
-        		genericType = adapter.getField().getGenericType();
-        	}
-        	else if (adapter.getReadMethod() != null)
-        	{
-        		genericType = adapter.getReadMethod().getGenericReturnType(); 
-        	}
-        	else if (adapter.getWriteMethod() != null)
-        	{
-        		genericType = adapter.getWriteMethod().getGenericParameterTypes()[0];
-        	}
-        	else
-        	{
-        		throw new RuntimeException("Could not find accessor for property " + adapter.getName());
-        	}
-        	
-        	return genericType == null ? adapter.getType() : genericType;
-		}
-
-		private void implementSetter(PropertyAdapter adapter)
-        {
-            if (adapter.getWriteMethod() != null)
-            {
-                implementSetter(adapter.getWriteMethod());
-                return;
-            }
-
-            if (adapter.getField() != null && adapter.isUpdate())
-            {
-                implementSetter(adapter.getField());
-                return;
-            }
-
-            implementNoOpMethod(ConduitMethods.SET, "Expression '%s' for class %s is read-only.", expression,
-                    rootType.getName());
-        }
-
-        private boolean isStatic(Member member)
-        {
-            return Modifier.isStatic(member.getModifiers());
-        }
-
-        private void implementSetter(final Field field)
-        {
-            if (isStatic(field))
-            {
-                plasticClass.introduceMethod(ConduitMethods.SET, new InstructionBuilderCallback()
-                {
-                    public void doBuild(InstructionBuilder builder)
-                    {
-                        builder.loadArgument(1).castOrUnbox(PlasticUtils.toTypeName(field.getType()));
-
-                        builder.putStaticField(field.getDeclaringClass().getName(), field.getName(), field.getType());
-
-                        builder.returnResult();
-                    }
-                });
-
-                return;
-            }
-
-            plasticClass.introduceMethod(ConduitMethods.SET, new InstructionBuilderCallback()
-            {
-                public void doBuild(InstructionBuilder builder)
-                {
-                    invokeNavigateMethod(builder);
-
-                    builder.loadArgument(1).castOrUnbox(PlasticUtils.toTypeName(field.getType()));
-
-                    builder.putField(field.getDeclaringClass().getName(), field.getName(), field.getType());
-
-                    builder.returnResult();
-                }
-            });
-        }
-
-        private void implementSetter(final Method writeMethod)
-        {
-            plasticClass.introduceMethod(ConduitMethods.SET, new InstructionBuilderCallback()
-            {
-                public void doBuild(InstructionBuilder builder)
-                {
-                    invokeNavigateMethod(builder);
-
-                    Class propertyType = writeMethod.getParameterTypes()[0];
-                    String propertyTypeName = PlasticUtils.toTypeName(propertyType);
-
-                    builder.loadArgument(1).castOrUnbox(propertyTypeName);
-
-                    builder.invoke(writeMethod);
-
-                    builder.returnResult();
-                }
-            });
-        }
-
-        private void implementGetter(PropertyAdapter adapter)
-        {
-            if (adapter.getReadMethod() != null)
-            {
-                implementGetter(adapter.getReadMethod());
-                return;
-            }
-
-            if (adapter.getField() != null)
-            {
-                implementGetter(adapter.getField());
-                return;
-            }
-
-            implementNoOpMethod(ConduitMethods.GET, "Expression '%s' for class %s is write-only.", expression,
-                    rootType.getName());
-        }
-
-        private void implementGetter(final Field field)
-        {
-            if (isStatic(field))
-            {
-                plasticClass.introduceMethod(ConduitMethods.GET, new InstructionBuilderCallback()
-                {
-                    public void doBuild(InstructionBuilder builder)
-                    {
-                        builder.getStaticField(field.getDeclaringClass().getName(), field.getName(), field.getType());
-
-                        // Cast not necessary here since the return type of get() is Object
-
-                        boxIfPrimitive(builder, field.getType());
-
-                        builder.returnResult();
-                    }
-                });
-
-                return;
-            }
-
-            plasticClass.introduceMethod(ConduitMethods.GET, new InstructionBuilderCallback()
-            {
-                public void doBuild(InstructionBuilder builder)
-                {
-                    invokeNavigateMethod(builder);
-
-                    builder.getField(field.getDeclaringClass().getName(), field.getName(), field.getType());
-
-                    // Cast not necessary here since the return type of get() is Object
-
-                    boxIfPrimitive(builder, field.getType());
-
-                    builder.returnResult();
-                }
-            });
-        }
-
-        private void implementGetter(final Method readMethod)
-        {
-            plasticClass.introduceMethod(ConduitMethods.GET, new InstructionBuilderCallback()
-            {
-                public void doBuild(InstructionBuilder builder)
-                {
-                    invokeNavigateMethod(builder);
-
-                    invokeMethod(builder, readMethod, null, 0);
-
-                    boxIfPrimitive(builder, conduitPropertyType);
-
-                    builder.returnResult();
-                }
-            });
-        }
-
-        private void implementRangeOpGetter(final Tree rangeNode)
-        {
-            plasticClass.introduceMethod(ConduitMethods.GET, new InstructionBuilderCallback()
-            {
-                public void doBuild(InstructionBuilder builder)
-                {
-                    // Put the delegate on top of the stack
-
-                    builder.loadThis().getField(getDelegateField());
-
-                    invokeMethod(builder, DelegateMethods.RANGE, rangeNode, 0);
-
-                    builder.returnResult();
-                }
-            });
-        }
-
-        /**
-         * @param node
-         *         subexpression to invert
-         */
-        private void implementNotOpGetter(final Tree node)
-        {
-            // Implement get() as navigate, then do a method invocation based on node
-            // then, then pass (wrapped) result to delegate.invert()
-
-            plasticClass.introduceMethod(ConduitMethods.GET, new InstructionBuilderCallback()
-            {
-                public void doBuild(InstructionBuilder builder)
-                {
-                    Type expressionType = implementNotExpression(builder, node);
-
-                    // Yes, we know this will always be the case, for now.
-
-                    boxIfPrimitive(builder, expressionType);
-
-                    builder.returnResult();
-                }
-            });
-        }
-
-        /**
-         * The first part of any implementation of get() or set(): invoke the navigation method
-         * and if the result is null, return immediately.
-         */
-        private void invokeNavigateMethod(InstructionBuilder builder)
-        {
-            builder.loadThis().loadArgument(0).invokeVirtual(navMethod);
-
-            builder.dupe().when(Condition.NULL, RETURN_NULL);
-        }
-
-        /**
-         * Uses the builder to add instructions for a subexpression.
-         *
-         * @param builder
-         *         used to add instructions
-         * @param activeType
-         *         type of value on top of the stack when this code will execute, or null if no value on stack
-         * @param node
-         *         defines the expression
-         * @return the expression type
-         */
-        private Type implementSubexpression(InstructionBuilder builder, Type activeType, Tree node)
-        {
-            Term term;
-
-            while (true)
-            {
-                switch (node.getType())
-                {
-                    case IDENTIFIER:
-                    case INVOKE:
-
-                        if (activeType == null)
-                        {
-                            invokeGetRootMethod(builder);
-
-                            activeType = rootType;
-                        }
-
-                        term = buildTerm(activeType, node);
-
-                        term.callback.doBuild(builder);
-
-                        return term.type;
-
-                    case INTEGER:
-
-                        builder.loadConstant(new Long(node.getText()));
-
-                        return long.class;
-
-                    case DECIMAL:
-
-                        builder.loadConstant(new Double(node.getText()));
-
-                        return double.class;
-
-                    case STRING:
-
-                        builder.loadConstant(node.getText());
-
-                        return String.class;
-
-                    case DEREF:
-                    case SAFEDEREF:
-
-                        if (activeType == null)
-                        {
-                            invokeGetRootMethod(builder);
-
-                            activeType = rootType;
-                        }
-
-                        term = analyzeDerefNode(activeType, node);
-
-                        term.callback.doBuild(builder);
-
-                        activeType = GenericsUtils.asClass(term.type);
-
-                        node = node.getChild(1);
-
-                        break;
-
-                    case TRUE:
-                    case FALSE:
-
-                        builder.loadConstant(node.getType() == TRUE ? 1 : 0);
-
-                        return boolean.class;
-
-                    case LIST:
-
-                        return implementListConstructor(builder, node);
-
-                    case MAP:
-                        return implementMapConstructor(builder, node);
-
-                    case NOT:
-
-                        return implementNotExpression(builder, node);
-
-                    case THIS:
-
-                        invokeGetRootMethod(builder);
-
-                        return rootType;
-
-                    case NULL:
-
-                        builder.loadNull();
-
-                        return Void.class;
-
-                    default:
-                        throw unexpectedNodeType(node, TRUE, FALSE, INTEGER, DECIMAL, STRING, DEREF, SAFEDEREF,
-                                IDENTIFIER, INVOKE, LIST, NOT, THIS, NULL);
-                }
-            }
-        }
-
-        public void invokeGetRootMethod(InstructionBuilder builder)
-        {
-            builder.loadThis().loadArgument(0).invokeVirtual(getRootMethod);
-        }
-
-        private void implementListGetter(final Tree listNode)
-        {
-            plasticClass.introduceMethod(ConduitMethods.GET, new InstructionBuilderCallback()
-            {
-                public void doBuild(InstructionBuilder builder)
-                {
-                    implementListConstructor(builder, listNode);
-
-                    builder.returnResult();
-                }
-            });
-        }
-
-        private Type implementListConstructor(InstructionBuilder builder, Tree listNode)
-        {
-            // First, create an empty instance of ArrayList
-
-            int count = listNode.getChildCount();
-
-            builder.newInstance(ArrayList.class);
-            builder.dupe().loadConstant(count).invokeConstructor(ArrayList.class, int.class);
-
-            for (int i = 0; i < count; i++)
-            {
-                builder.dupe(); // the ArrayList
-
-                Type expressionType = implementSubexpression(builder, null, listNode.getChild(i));
-
-                boxIfPrimitive(builder, GenericsUtils.asClass(expressionType));
-
-                // Add the value to the array, then pop off the returned boolean
-                builder.invoke(ArrayListMethods.ADD).pop();
-            }
-
-            return ArrayList.class;
-        }
-
-        private void implementMapGetter(final Tree mapNode)
-        {
-            plasticClass.introduceMethod(ConduitMethods.GET, new InstructionBuilderCallback()
-            {
-                public void doBuild(InstructionBuilder builder)
-                {
-                    implementMapConstructor(builder, mapNode);
-
-                    builder.returnResult();
-                }
-            });
-        }
-
-        private Type implementMapConstructor(InstructionBuilder builder, Tree mapNode)
-        {
-            int count = mapNode.getChildCount();
-            builder.newInstance(HashMap.class);
-            builder.dupe().loadConstant(count).invokeConstructor(HashMap.class, int.class);
-
-            for (int i = 0; i < count; i += 2)
-            {
-                builder.dupe();
-
-                //build the key:
-                Type keyType = implementSubexpression(builder, null, mapNode.getChild(i));
-                boxIfPrimitive(builder, GenericsUtils.asClass(keyType));
-
-                //and the value:
-                Type valueType = implementSubexpression(builder, null, mapNode.getChild(i + 1));
-                boxIfPrimitive(builder, GenericsUtils.asClass(valueType));
-
-                //put the value into the array, then pop off the returned object.
-                builder.invoke(HashMapMethods.PUT).pop();
-
-            }
-
-            return HashMap.class;
-        }
-
-
-        private void implementNoOpSetter()
-        {
-            implementNoOpMethod(ConduitMethods.SET, "Expression '%s' for class %s is read-only.", expression,
-                    rootType.getName());
-        }
-
-        public void implementNoOpMethod(MethodDescription method, String format, Object... arguments)
-        {
-            final String message = String.format(format, arguments);
-
-            plasticClass.introduceMethod(method).changeImplementation(new InstructionBuilderCallback()
-            {
-                public void doBuild(InstructionBuilder builder)
-                {
-                    builder.throwException(RuntimeException.class, message);
-                }
-            });
-        }
-
-        /**
-         * Invokes a method that may take parameters. The children of the invokeNode are subexpressions
-         * to be evaluated, and potentially coerced, so that they may be passed to the method.
-         *
-         * @param builder
-         *         constructs code
-         * @param method
-         *         method to invoke
-         * @param node
-         *         INVOKE or RANGEOP node
-         * @param childOffset
-         *         offset within the node to the first child expression (1 in an INVOKE node because the
-         *         first child is the method name, 0 in a RANGEOP node)
-         */
-        private void invokeMethod(InstructionBuilder builder, Method method, Tree node, int childOffset)
-        {
-            // We start with the target object for the method on top of the stack.
-            // Next, we have to push each method parameter, which may include boxing/deboxing
-            // and coercion. Once the code is in good shape, there's a lot of room to optimize
-            // the bytecode (a bit too much boxing/deboxing occurs, as well as some unnecessary
-            // trips through TypeCoercer). We might also want to have a local variable to store
-            // the root object (result of getRoot()).
-
-            Class[] parameterTypes = method.getParameterTypes();
-
-            for (int i = 0; i < parameterTypes.length; i++)
-            {
-                Type expressionType = implementSubexpression(builder, null, node.getChild(i + childOffset));
-
-                // The value left on the stack is not primitive, and expressionType represents
-                // its real type.
-
-                Class parameterType = parameterTypes[i];
-
-                if (!parameterType.isAssignableFrom(GenericsUtils.asClass(expressionType)))
-                {
-                    boxIfPrimitive(builder, expressionType);
-
-                    builder.loadThis().getField(getDelegateField());
-                    builder.swap().loadTypeConstant(PlasticUtils.toWrapperType(parameterType));
-                    builder.invoke(DelegateMethods.COERCE);
-
-                    if (parameterType.isPrimitive())
-                    {
-                        builder.castOrUnbox(parameterType.getName());
-                    } else
-                    {
-                        builder.checkcast(parameterType);
-                    }
-                }
-
-                // And that should leave an object of the correct type on the stack,
-                // ready for the method invocation.
-            }
-
-            // Now the target object and all parameters are in place.
-
-            builder.invoke(method.getDeclaringClass(), method.getReturnType(), method.getName(),
-                    method.getParameterTypes());
-        }
-
-        /**
-         * Analyzes a DEREF or SAFEDEREF node, proving back a term that identifies its type and provides a callback to
-         * peform the dereference.
-         *
-         * @return a term indicating the type of the expression to this point, and a {@link InstructionBuilderCallback}
-         *         to advance the evaluation of the expression form the previous value to the current
-         */
-        private Term analyzeDerefNode(Type activeType, Tree node)
-        {
-            // The first child is the term.
-
-            Tree term = node.getChild(0);
-
-            boolean allowNull = node.getType() == SAFEDEREF;
-
-            return buildTerm(activeType, term, allowNull ? NullHandling.ALLOW : NullHandling.FORBID);
-        }
-
-        private Term buildTerm(Type activeType, Tree term, final NullHandling nullHandling)
-        {
-            assertNodeType(term, IDENTIFIER, INVOKE);
-
-            final Term simpleTerm = buildTerm(activeType, term);
-
-            if (simpleTerm.genericType.isPrimitive())
-                return simpleTerm;
-
-            return simpleTerm.withCallback(new InstructionBuilderCallback()
-            {
-                public void doBuild(InstructionBuilder builder)
-                {
-                    simpleTerm.callback.doBuild(builder);
-
-                    builder.dupe().when(Condition.NULL, new InstructionBuilderCallback()
-                    {
-                        public void doBuild(InstructionBuilder builder)
-                        {
-                            switch (nullHandling)
-                            {
-                                // It is necessary to load a null onto the stack (even if there's already one
-                                // there) because of the verifier. It sees the return when the stack contains an
-                                // intermediate value (along the navigation chain) and thinks the method is
-                                // returning a value of the wrong type.
-
-                                case ALLOW:
-                                    builder.loadNull().returnResult();
-
-                                case FORBID:
-
-                                    builder.loadConstant(simpleTerm.description);
-                                    builder.loadConstant(expression);
-                                    builder.loadArgument(0);
-
-                                    builder.invokeStatic(PropertyConduitSourceImpl.class, NullPointerException.class,
-                                            "nullTerm", String.class, String.class, Object.class);
-                                    builder.throwException();
-
-                                    break;
-
-                            }
-                        }
-                    });
-                }
-            });
-        }
-
-        private void assertNodeType(Tree node, int... expected)
-        {
-            int type = node.getType();
-
-            for (int e : expected)
-            {
-                if (type == e)
-                    return;
-            }
-
-            throw unexpectedNodeType(node, expected);
-        }
-
-        private RuntimeException unexpectedNodeType(Tree node, int... expected)
-        {
-            List<String> tokenNames = CollectionFactory.newList();
-
-            for (int i = 0; i < expected.length; i++)
-                tokenNames.add(PropertyExpressionParser.tokenNames[expected[i]]);
-
-            String message = String.format("Node %s was type %s, but was expected to be (one of) %s.",
-                    node.toStringTree(), PropertyExpressionParser.tokenNames[node.getType()],
-                    InternalUtils.joinSorted(tokenNames));
-
-            return new RuntimeException(message);
-        }
-
-        private Term buildTerm(Type activeType, Tree termNode)
-        {
-            switch (termNode.getType())
-            {
-                case INVOKE:
-
-                    return buildInvokeTerm(activeType, termNode);
-
-                case IDENTIFIER:
-
-                    return buildPropertyAccessTerm(activeType, termNode);
-
-                default:
-                    throw unexpectedNodeType(termNode, INVOKE, IDENTIFIER);
-            }
-        }
-
-        private Term buildPropertyAccessTerm(Type activeType, Tree termNode)
-        {
-            String propertyName = termNode.getText();
-
-            PropertyAdapter adapter = findPropertyAdapter(activeType, propertyName);
-
-            // Prefer the accessor over the field
-
-            if (adapter.getReadMethod() != null)
-            {
-                return buildGetterMethodAccessTerm(activeType, propertyName,
-                        adapter.getReadMethod());
-            }
-
-            if (adapter.getField() != null)
-            {
-                return buildPublicFieldAccessTerm(activeType, propertyName,
-                        adapter.getField());
-            }
-
-            throw new RuntimeException(String.format(
-                    "Property '%s' of class %s is not readable (it has no read accessor method).", adapter.getName(),
-                    adapter.getBeanType().getName()));
-        }
-
-        public PropertyAdapter findPropertyAdapter(Type activeType, String propertyName)
-        {
-            Class activeClass = GenericsUtils.asClass(activeType);
-
-            ClassPropertyAdapter classAdapter = access.getAdapter(activeClass);
-            PropertyAdapter adapter = classAdapter.getPropertyAdapter(propertyName);
-
-            if (adapter == null)
-            {
-                final List<String> names = classAdapter.getPropertyNames();
-                final String className = activeClass.getName();
-                throw new UnknownValueException(String.format(
-                        "Class %s does not contain a property (or public field) named '%s'.", className, propertyName),
-                        new AvailableValues("Properties (and public fields)", names));
-            }
-            return adapter;
-        }
-
-        private Term buildGetterMethodAccessTerm(final Type activeType, String propertyName, final Method readMethod)
-        {
-            Type returnType = GenericsUtils.extractActualType(activeType, readMethod);
-
-            return new Term(returnType, propertyName, new InstructionBuilderCallback()
-            {
-                public void doBuild(InstructionBuilder builder)
-                {
-                    invokeMethod(builder, readMethod, null, 0);
-
-                    Type genericType = GenericsUtils.extractActualType(activeType, readMethod);
-
-                    castToGenericType(builder, readMethod.getReturnType(), genericType);
-                }
-            });
-        }
-
-        private Term buildPublicFieldAccessTerm(Type activeType, String propertyName, final Field field)
-        {
-            final Type fieldType = GenericsUtils.extractActualType(activeType, field);
-
-            return new Term(fieldType, propertyName, new InstructionBuilderCallback()
-            {
-                public void doBuild(InstructionBuilder builder)
-                {
-                    Class rawFieldType = field.getType();
-
-                    String rawTypeName = PlasticUtils.toTypeName(rawFieldType);
-                    String containingClassName = field.getDeclaringClass().getName();
-                    String fieldName = field.getName();
-
-                    if (isStatic(field))
-                    {
-                        // We've gone to the trouble of loading the root object, or navigated to some other object,
-                        // but we don't need or want the instance, since it's a static field we're accessing.
-                        // Ideally, we would optimize this, and only generate and invoke the getRoot() and nav() methods as needed, but
-                        // access to public fields is relatively rare, and the cost is just the unused bytecode.
-
-                        builder.pop();
-
-                        builder.getStaticField(containingClassName, fieldName, rawTypeName);
-
-                    } else
-                    {
-                        builder.getField(containingClassName, fieldName, rawTypeName);
-                    }
-
-                    castToGenericType(builder, rawFieldType, fieldType);
-                }
-
-            });
-        }
-
-        /**
-         * Casts the results of a field read or method invocation based on generic information.
-         *
-         * @param builder
-         *         used to add instructions
-         * @param rawType
-         *         the simple type (often Object) of the field (or method return type)
-         * @param genericType
-         *         the generic Type, from which parameterizations can be determined
-         */
-        private void castToGenericType(InstructionBuilder builder, Class rawType, final Type genericType)
-        {
-            if (!genericType.equals(rawType))
-            {
-                Class castType = GenericsUtils.asClass(genericType);
-                builder.checkcast(castType);
-            }
-        }
-
-        private Term buildInvokeTerm(final Type activeType, final Tree invokeNode)
-        {
-            String methodName = invokeNode.getChild(0).getText();
-
-            int parameterCount = invokeNode.getChildCount() - 1;
-
-            Class activeClass = GenericsUtils.asClass(activeType);
-
-            final Method method = findMethod(activeClass, methodName, parameterCount);
-
-            if (method.getReturnType().equals(void.class))
-                throw new RuntimeException(String.format("Method %s.%s() returns void.", activeClass.getName(),
-                        methodName));
-
-            Type returnType = GenericsUtils.extractActualType(activeType, method);
-
-            return new Term(returnType, toUniqueId(method), InternalUtils.toAnnotationProvider(method), new InstructionBuilderCallback()
-            {
-                public void doBuild(InstructionBuilder builder)
-                {
-                    invokeMethod(builder, method, invokeNode, 1);
-
-                    Type genericType = GenericsUtils.extractActualType(activeType, method);
-
-                    castToGenericType(builder, method.getReturnType(), genericType);
-                }
-            }
-            );
-        }
-
-        private Method findMethod(Class activeType, String methodName, int parameterCount)
-        {
-            Class searchType = activeType;
-
-            while (true)
-            {
-
-                for (Method method : searchType.getMethods())
-                {
-                    if (method.getParameterTypes().length == parameterCount
-                            && method.getName().equalsIgnoreCase(methodName))
-                        return method;
-                }
-
-                // TAP5-330
-                if (searchType != Object.class)
-                {
-                    searchType = Object.class;
-                } else
-                {
-                    throw new RuntimeException(String.format("Class %s does not contain a public method named '%s()'.",
-                            activeType.getName(), methodName));
-                }
-            }
-        }
-
-        public void boxIfPrimitive(InstructionBuilder builder, Type termType)
-        {
-            boxIfPrimitive(builder, GenericsUtils.asClass(termType));
-        }
-
-        public void boxIfPrimitive(InstructionBuilder builder, Class termType)
-        {
-            if (termType.isPrimitive())
-                builder.boxPrimitive(termType.getName());
-        }
-
-        public Class implementNotExpression(InstructionBuilder builder, final Tree notNode)
-        {
-            Type expressionType = implementSubexpression(builder, null, notNode.getChild(0));
-
-            boxIfPrimitive(builder, expressionType);
-
-            // Now invoke the delegate invert() method
-
-            builder.loadThis().getField(getDelegateField());
-
-            builder.swap().invoke(DelegateMethods.INVERT);
-
-            return boolean.class;
-        }
-
-        /**
-         * Defer creation of the delegate field unless actually needed.
-         */
-        private PlasticField getDelegateField()
-        {
-            if (delegateField == null)
-                delegateField = plasticClass.introduceField(PropertyConduitDelegate.class, "delegate").inject(
-                        sharedDelegate);
-
-            return delegateField;
-        }
-    }
-
-    public PropertyConduitSourceImpl(PropertyAccess access, @ComponentLayer
-    PlasticProxyFactory proxyFactory, TypeCoercer typeCoercer, StringInterner interner)
-    {
-        this.access = access;
-        this.proxyFactory = proxyFactory;
-        this.typeCoercer = typeCoercer;
-        this.interner = interner;
-
-        literalTrue = createLiteralConduit(Boolean.class, true);
-        literalFalse = createLiteralConduit(Boolean.class, false);
-        literalNull = createLiteralConduit(Void.class, null);
-
-        sharedDelegate = new PropertyConduitDelegate(typeCoercer);
-    }
-
-    @PostInjection
-    public void listenForInvalidations(@ComponentClasses InvalidationEventHub hub)
-    {
-        hub.clearOnInvalidation(cache);
-    }
-
-
-    public PropertyConduit create(Class rootClass, String expression)
-    {
-        assert rootClass != null;
-        assert InternalUtils.isNonBlank(expression);
-
-        MultiKey key = new MultiKey(rootClass, expression);
-
-        PropertyConduit result = cache.get(key);
-
-        if (result == null)
-        {
-            result = build(rootClass, expression);
-            cache.put(key, result);
-        }
-
-        return result;
-    }
-
-    /**
-     * Builds a subclass of {@link PropertyConduitDelegate} that implements the
-     * get() and set() methods and overrides the
-     * constructor. In a worst-case race condition, we may build two (or more)
-     * conduits for the same
-     * rootClass/expression, and it will get sorted out when the conduit is
-     * stored into the cache.
-     *
-     * @param rootClass
-     *         class of root object for expression evaluation
-     * @param expression
-     *         expression to be evaluated
-     * @return the conduit
-     */
-    private PropertyConduit build(final Class rootClass, String expression)
-    {
-        Tree tree = parse(expression);
-
-        try
-        {
-            switch (tree.getType())
-            {
-                case TRUE:
-
-                    return literalTrue;
-
-                case FALSE:
-
-                    return literalFalse;
-
-                case NULL:
-
-                    return literalNull;
-
-                case INTEGER:
-
-                    // Leading '+' may screw this up.
-                    // TODO: Singleton instance for "0", maybe "1"?
-
-                    return createLiteralConduit(Long.class, new Long(tree.getText()));
-
-                case DECIMAL:
-
-                    // Leading '+' may screw this up.
-                    // TODO: Singleton instance for "0.0"?
-
-                    return createLiteralConduit(Double.class, new Double(tree.getText()));
-
-                case STRING:
-
-                    return createLiteralConduit(String.class, tree.getText());
-
-                case RANGEOP:
-
-                    Tree fromNode = tree.getChild(0);
-                    Tree toNode = tree.getChild(1);
-
-                    // If the range is defined as integers (not properties, etc.)
-                    // then it is possible to calculate the value here, once, and not
-                    // build a new class.
-
-                    if (fromNode.getType() != INTEGER || toNode.getType() != INTEGER)
-                        break;
-
-                    int from = Integer.parseInt(fromNode.getText());
-                    int to = Integer.parseInt(toNode.getText());
-
-                    IntegerRange ir = new IntegerRange(from, to);
-
-                    return createLiteralConduit(IntegerRange.class, ir);
-
-                case THIS:
-
-                    return createLiteralThisPropertyConduit(rootClass);
-
-                default:
-                    break;
-            }
-
-            return proxyFactory.createProxy(InternalPropertyConduit.class,
-                    new PropertyConduitBuilder(rootClass, expression, tree)).newInstance();
-        } catch (Exception ex)
-        {
-            throw new PropertyExpressionException(String.format("Exception generating conduit for expression '%s': %s",
-                    expression, ExceptionUtils.toMessage(ex)), expression, ex);
-        }
-    }
-
-    private PropertyConduit createLiteralThisPropertyConduit(final Class rootClass)
-    {
-        return new PropertyConduit()
-        {
-            public Object get(Object instance)
-            {
-                return instance;
-            }
-
-            public void set(Object instance, Object value)
-            {
-                throw new RuntimeException("Literal values are not updateable.");
-            }
-
-            public Class getPropertyType()
-            {
-                return rootClass;
-            }
-            
-            public Type getPropertyGenericType()
-            {
-            	return rootClass;
-            }
-
-            public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
-            {
-                return invariantAnnotationProvider.getAnnotation(annotationClass);
-            }
-        };
-    }
-
-    private <T> PropertyConduit createLiteralConduit(Class<T> type, T value)
-    {
-        return new LiteralPropertyConduit(typeCoercer, type, invariantAnnotationProvider, interner.format(
-                "LiteralPropertyConduit[%s]", value), value);
-    }
-
-    private Tree parse(String expression)
-    {
-        InputStream is = new ByteArrayInputStream(expression.getBytes());
-
-        ANTLRInputStream ais;
-
-        try
-        {
-            ais = new ANTLRInputStream(is);
-        } catch (IOException ex)
-        {
-            throw new RuntimeException(ex);
-        }
-
-        PropertyExpressionLexer lexer = new PropertyExpressionLexer(ais);
-
-        CommonTokenStream tokens = new CommonTokenStream(lexer);
-
-        PropertyExpressionParser parser = new PropertyExpressionParser(tokens);
-
-        try
-        {
-            return (Tree) parser.start().getTree();
-        } catch (Exception ex)
-        {
-            throw new RuntimeException(String.format("Error parsing property expression '%s': %s.", expression,
-                    ex.getMessage()), ex);
-        }
-    }
-
-    /**
-     * May be invoked from fabricated PropertyConduit instances.
-     */
-    @SuppressWarnings("unused")
-    public static NullPointerException nullTerm(String term, String expression, Object root)
-    {
-        String message = String.format("Property '%s' (within property expression '%s', of %s) is null.", term,
-                expression, root);
-
-        return new NullPointerException(message);
-    }
-
-    private static String toUniqueId(Method method)
-    {
-        StringBuilder builder = new StringBuilder(method.getName()).append("(");
-        String sep = "";
-
-        for (Class parameterType : method.getParameterTypes())
-        {
-            builder.append(sep);
-            builder.append(PlasticUtils.toTypeName(parameterType));
-
-            sep = ",";
-        }
-
-        return builder.append(")").toString();
-    }
-}

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/f963c7ab/tapestry-core/src/main/java/org/apache/tapestry5/internal/util/IntegerRange.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/util/IntegerRange.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/util/IntegerRange.java
deleted file mode 100644
index 7b2b7ab..0000000
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/util/IntegerRange.java
+++ /dev/null
@@ -1,125 +0,0 @@
-// Copyright 2006 The Apache Software Foundation
-//
-// 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.
-
-package org.apache.tapestry5.internal.util;
-
-import java.util.Iterator;
-
-/**
- * Represents a sequence of integer values, either ascending or descending. The sequence is always inclusive (of the
- * finish value).
- */
-public final class IntegerRange implements Iterable<Integer>
-{
-    private final int start;
-
-    private final int finish;
-
-    private class RangeIterator implements Iterator<Integer>
-    {
-        private final int increment;
-
-        private int value = start;
-
-        private boolean hasNext = true;
-
-        RangeIterator()
-        {
-            increment = start < finish ? +1 : -1;
-        }
-
-        public boolean hasNext()
-        {
-            return hasNext;
-        }
-
-        public Integer next()
-        {
-            if (!hasNext) throw new IllegalStateException();
-
-            int result = value;
-
-            hasNext = value != finish;
-
-            value += increment;
-
-            return result;
-        }
-
-        public void remove()
-        {
-            throw new UnsupportedOperationException();
-        }
-
-    }
-
-    public IntegerRange(final int start, final int finish)
-    {
-        this.start = start;
-        this.finish = finish;
-    }
-
-    public int getFinish()
-    {
-        return finish;
-    }
-
-    public int getStart()
-    {
-        return start;
-    }
-
-    @Override
-    public String toString()
-    {
-        return String.format("%d..%d", start, finish);
-    }
-
-    /**
-     * The main puprose of a range object is to produce an Iterator. Since IntegerRange is iterable, it is useful with
-     * the Tapestry Loop component, but also with the Java for loop!
-     */
-    public Iterator<Integer> iterator()
-    {
-        return new RangeIterator();
-    }
-
-    @Override
-    public int hashCode()
-    {
-        final int PRIME = 31;
-
-        int result = PRIME + finish;
-
-        result = PRIME * result + start;
-
-        return result;
-    }
-
-    /**
-     * Returns true if the other object is an IntegerRange with the same start and finish values.
-     */
-    @Override
-    public boolean equals(Object obj)
-    {
-        if (this == obj) return true;
-        if (obj == null) return false;
-        if (getClass() != obj.getClass()) return false;
-        final IntegerRange other = (IntegerRange) obj;
-        if (finish != other.finish) return false;
-
-        return start == other.start;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/f963c7ab/tapestry-core/src/main/java/org/apache/tapestry5/internal/util/MultiKey.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/util/MultiKey.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/util/MultiKey.java
deleted file mode 100644
index 503bb1f..0000000
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/util/MultiKey.java
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright 2006 The Apache Software Foundation
-//
-// 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.
-
-package org.apache.tapestry5.internal.util;
-
-import java.util.Arrays;
-
-/**
- * Combines multiple values to form a single composite key. MultiKey can often be used as an alternative to nested
- * maps.
- */
-public final class MultiKey
-{
-    private static final int PRIME = 31;
-
-    private final Object[] values;
-
-    private final int hashCode;
-
-    /**
-     * Creates a new instance from the provided values. It is assumed that the values provided are good map keys
-     * themselves -- immutable, with proper implementations of equals() and hashCode().
-     *
-     * @param values
-     */
-    public MultiKey(Object... values)
-    {
-        this.values = values;
-
-        hashCode = PRIME * Arrays.hashCode(this.values);
-    }
-
-    @Override
-    public int hashCode()
-    {
-        return hashCode;
-    }
-
-    @Override
-    public boolean equals(Object obj)
-    {
-        if (this == obj)
-            return true;
-        if (obj == null)
-            return false;
-        if (getClass() != obj.getClass())
-            return false;
-        final MultiKey other = (MultiKey) obj;
-
-        return Arrays.equals(values, other.values);
-    }
-
-    @Override
-    public String toString()
-    {
-        StringBuilder builder = new StringBuilder("MultiKey[");
-
-        boolean first = true;
-
-        for (Object o : values)
-        {
-            if (!first)
-                builder.append(", ");
-
-            builder.append(o);
-
-            first = false;
-        }
-
-        builder.append("]");
-
-        return builder.toString();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/f963c7ab/tapestry-core/src/main/java/org/apache/tapestry5/services/BeanModelSource.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/services/BeanModelSource.java b/tapestry-core/src/main/java/org/apache/tapestry5/services/BeanModelSource.java
deleted file mode 100644
index 16b4fca..0000000
--- a/tapestry-core/src/main/java/org/apache/tapestry5/services/BeanModelSource.java
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2007, 2008 The Apache Software Foundation
-//
-// 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.
-
-package org.apache.tapestry5.services;
-
-import org.apache.tapestry5.beaneditor.BeanModel;
-import org.apache.tapestry5.ioc.Messages;
-
-/**
- * Used by a component to create a default {@link org.apache.tapestry5.beaneditor.BeanModel} for a particular bean
- * class. Also provides support to the model by generating validation information for individual fields.
- * <p/>
- * BeanModels are the basis for the {@link org.apache.tapestry5.corelib.components.BeanEditor} and {@link
- * org.apache.tapestry5.corelib.components.Grid} comopnents.
- *
- * @see org.apache.tapestry5.services.PropertyConduitSource
- */
-public interface BeanModelSource
-{
-    /**
-     * Creates a new model used for editing the indicated bean class. The model will represent all read/write properties
-     * of the bean. The order of properties is determined from the order of the getter methods in the code, and can be
-     * overridden with the {@link org.apache.tapestry5.beaneditor.ReorderProperties} annotation. The labels for the
-     * properties are derived from the property names, but if the component's message catalog has keys of the form
-     * <code>propertyName-label</code>, then those will be used instead.
-     * <p/>
-     * Models are <em>mutable</em>, so they are not cached, a fresh instance is created each time.
-     *
-     * @param beanClass                class of object to be edited
-     * @param filterReadOnlyProperties if true, then properties that are read-only will be skipped (leaving only
-     *                                 read-write properties, appropriate for {@link org.apache.tapestry5.corelib.components.BeanEditForm},
-     *                                 etc.). If false, then both read-only and read-write properties will be included
-     *                                 (appropriate for {@link org.apache.tapestry5.corelib.components.Grid} or {@link
-     *                                 org.apache.tapestry5.corelib.components.BeanDisplay}).
-     * @param messages                 Used to find explicit overrides of
-     * @return a model
-     * @deprecated use {@link #createDisplayModel(Class, org.apache.tapestry5.ioc.Messages)} or {@link
-     *             #createEditModel(Class, org.apache.tapestry5.ioc.Messages)}
-     */
-    <T> BeanModel<T> create(Class<T> beanClass, boolean filterReadOnlyProperties, Messages messages);
-
-    /**
-     * Creates a model for display purposes; this may include properties which are read-only.
-     *
-     * @param beanClass class of object to be edited
-     * @param messages
-     * @return a model containing properties that can be presented to the user
-     */
-    <T> BeanModel<T> createDisplayModel(Class<T> beanClass, Messages messages);
-
-    /**
-     * Creates a model for edit and update purposes, only properties that are fully read-write are included.
-     *
-     * @param beanClass class of object to be edited
-     * @param messages
-     * @return a model containing properties that can be presented to the user
-     */
-    <T> BeanModel<T> createEditModel(Class<T> beanClass, Messages messages);
-}

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/f963c7ab/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentClasses.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentClasses.java b/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentClasses.java
deleted file mode 100644
index c901d3a..0000000
--- a/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentClasses.java
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2008, 2010 The Apache Software Foundation
-//
-// 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.
-
-package org.apache.tapestry5.services;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Marker annotation used to inject the correct {@link org.apache.tapestry5.services.InvalidationEventHub} service
- * responsible for invalidations when underlying component class files are changed.
- * 
- * @since 5.1.0.0
- */
-@Target(
-{ ElementType.PARAMETER, ElementType.FIELD, ElementType.METHOD })
-@Retention(RetentionPolicy.RUNTIME)
-@Documented
-public @interface ComponentClasses
-{
-}

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/f963c7ab/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentLayer.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentLayer.java b/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentLayer.java
deleted file mode 100644
index e342c3f..0000000
--- a/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentLayer.java
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2007 The Apache Software Foundation
-//
-// 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.
-
-package org.apache.tapestry5.services;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-/**
- * Marker annotation used to identify a service from the component layer that conflicts, in terms of service interface,
- * with a service from elsewhere. In particular, this is used to disambiguate {@link org.apache.tapestry5.ioc.services.PlasticProxyFactory} which has one implementation (marked with {@link
- * org.apache.tapestry5.ioc.services.Builtin} and another with this annotation.
- */
-@Target(
-        {PARAMETER, FIELD})
-@Retention(RUNTIME)
-@Documented
-public @interface ComponentLayer
-{
-
-}

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/f963c7ab/tapestry-core/src/main/java/org/apache/tapestry5/services/InvalidationEventHub.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/services/InvalidationEventHub.java b/tapestry-core/src/main/java/org/apache/tapestry5/services/InvalidationEventHub.java
deleted file mode 100644
index 77b028e..0000000
--- a/tapestry-core/src/main/java/org/apache/tapestry5/services/InvalidationEventHub.java
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2006, 2007, 2008, 2011, 2012 The Apache Software Foundation
-//
-// 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.
-
-package org.apache.tapestry5.services;
-
-import java.util.Map;
-
-/**
- * An object which manages a list of {@link org.apache.tapestry5.services.InvalidationListener}s. There are multiple
- * event hub services implementing this interface, each with a specific marker annotation; each can register listeners
- * and fire events; these are based on the type of resource that has been invalidated. Tapestry has built-in support
- * for:
- * <dl>
- * <dt>message catalog resources
- * <dd>{@link org.apache.tapestry5.services.ComponentMessages} marker annotation
- * <dt>component templates
- * <dd>{@link org.apache.tapestry5.services.ComponentTemplates} marker annotation
- * <dt>component classes
- * <dd>{@link org.apache.tapestry5.services.ComponentClasses} marker annotation
- * </dl>
- * <p/>
- * Starting in Tapestry 5.3, these services are disabled in production (it does nothing).
- *
- * @since 5.1.0.0
- */
-public interface InvalidationEventHub
-{
-    /**
-     * Adds a listener, who needs to know when an underlying resource of a given category has changed (so that the
-     * receiver may discard any cached data that may have been invalidated). Does nothing in production mode.
-     *
-     * @deprecated in 5.4, use {@link #addInvalidationCallback(Runnable)} instead}
-     */
-    void addInvalidationListener(InvalidationListener listener);
-
-    /**
-     * Adds a callback that is invoked when an underlying tracked resource has changed. Does nothing in production mode.
-     *
-     * @since  5.4
-     */
-    void addInvalidationCallback(Runnable callback);
-
-    /**
-     * Adds a callback that clears the map.
-     *
-     * @since 5.4
-     */
-    void clearOnInvalidation(Map<?,?> map);
-}

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/f963c7ab/tapestry-core/src/main/java/org/apache/tapestry5/services/InvalidationListener.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/services/InvalidationListener.java b/tapestry-core/src/main/java/org/apache/tapestry5/services/InvalidationListener.java
deleted file mode 100644
index b9b4aa3..0000000
--- a/tapestry-core/src/main/java/org/apache/tapestry5/services/InvalidationListener.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2006, 2007, 2012 The Apache Software Foundation
-//
-// 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.
-
-package org.apache.tapestry5.services;
-
-/**
- * Interface for objects that may cache information that can be invalidated. Invalidation occurs when external files,
- * from which in-memory data is cached, is determined to have changed. Granularity is very limited; when any external
- * file is found to have changed, the event is fired (with the expectation that the cleared cache will be repopulated as
- * necessary).
- *
- * @see org.apache.tapestry5.services.InvalidationEventHub
- * @since 5.1.0.0
- * @deprecated In 5.4; use {@link InvalidationEventHub#addInvalidationCallback(Runnable)} instead
- */
-public interface InvalidationListener
-{
-    /**
-     * Invoked to indicate that some object is invalid. The receiver should clear its cache.
-     */
-    void objectWasInvalidated();
-}

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/f963c7ab/tapestry-core/src/main/java/org/apache/tapestry5/services/PropertyConduitSource.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/services/PropertyConduitSource.java b/tapestry-core/src/main/java/org/apache/tapestry5/services/PropertyConduitSource.java
deleted file mode 100644
index 312cd60..0000000
--- a/tapestry-core/src/main/java/org/apache/tapestry5/services/PropertyConduitSource.java
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2007, 2008, 2009 The Apache Software Foundation
-//
-// 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.
-
-package org.apache.tapestry5.services;
-
-import org.apache.tapestry5.PropertyConduit;
-
-/**
- * A source for {@link org.apache.tapestry5.PropertyConduit}s, which can be thought of as a compiled property path
- * expression. PropertyConduits are the basis of the "prop:" binding factory, thus this service defines the expression
- * format used by the {@link org.apache.tapestry5.internal.bindings.PropBindingFactory}.
- */
-public interface PropertyConduitSource
-{
-    /**
-     * Returns a property conduit instance for the given expression. PropertyConduitSource caches the conduits it
-     * returns, so despite the name, this method does not always create a <em>new</em> conduit. The cache is cleared if
-     * a change to component classes is observed.
-     * <p/>
-     * Callers of this method should observe notifications from the {@link org.apache.tapestry5.services.InvalidationEventHub}
-     * for {@link org.apache.tapestry5.services.ComponentClasses} and discard any aquired conduits; failure to do so
-     * will create memory leaks whenever component classes change (the conduits will keep references to the old classes
-     * and classloaders).
-     *
-     * @param rootType   the type of the root object to which the expression is applied
-     * @param expression expression to be evaluated on instances of the root class
-     * @return RuntimeException if the expression is invalid (poorly formed, references non-existent properties, etc.)
-     */
-    PropertyConduit create(Class rootType, String expression);
-}

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/f963c7ab/tapestry-ioc/build.gradle
----------------------------------------------------------------------
diff --git a/tapestry-ioc/build.gradle b/tapestry-ioc/build.gradle
index e890f7e..5a5321f 100644
--- a/tapestry-ioc/build.gradle
+++ b/tapestry-ioc/build.gradle
@@ -4,6 +4,7 @@ dependencies {
     compile project(':tapestry-func')
     compile project(':tapestry5-annotations')
     compile project(":plastic")
+    compile project(":beanmodel")
 
     provided project(':tapestry-test')
 

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/f963c7ab/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/AnnotationProvider.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/AnnotationProvider.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/AnnotationProvider.java
deleted file mode 100644
index 1f0e744..0000000
--- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/AnnotationProvider.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2007, 2011 The Apache Software Foundation
-//
-// 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.
-
-package org.apache.tapestry5.ioc;
-
-import java.lang.annotation.Annotation;
-
-/**
- * A source of annotations. This interface is used to mask where the annotations come from (for example, from a Method,
- * a Class, or some other source).
- */
-public interface AnnotationProvider
-{
-    /**
-     * Searches for the specified annotation, returning the matching annotation instance.
-     *
-     * @param <T>
-     * @param annotationClass used to select the annotation to return
-     * @return the annotation, or null if not found
-     */
-    <T extends Annotation> T getAnnotation(Class<T> annotationClass);
-}

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/f963c7ab/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/Locatable.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/Locatable.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/Locatable.java
deleted file mode 100644
index 37b6551..0000000
--- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/Locatable.java
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2006, 2008 The Apache Software Foundation
-//
-// 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.
-
-package org.apache.tapestry5.ioc;
-
-/**
- * Interface implemented by objects which carry a location tag. Defines a readable property, location.
- */
-@SuppressWarnings({"JavaDoc"})
-public interface Locatable
-{
-    /**
-     * Returns the location associated with this object for error reporting purposes.
-     */
-    Location getLocation();
-}

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/f963c7ab/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/Location.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/Location.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/Location.java
deleted file mode 100644
index e6688c2..0000000
--- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/Location.java
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2006 The Apache Software Foundation
-//
-// 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.
-
-package org.apache.tapestry5.ioc;
-
-/**
- * A kind of tag applied to other objects to identify where they came from, in terms of a file (the resource), a line
- * number, and a column number. This is part of "line precise exception reporting", whereby errors at runtime can be
- * tracked backwards to the files from which they were parsed or otherwise constructed.
- */
-public interface Location
-{
-    /**
-     * The resource from which the object tagged with a location was derived.
-     */
-    Resource getResource();
-
-    /**
-     * The line number within the resource, if known, or -1 otherwise.
-     */
-    int getLine();
-
-    /**
-     * The column number within the line if known, or -1 otherwise.
-     */
-    int getColumn();
-}

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/f963c7ab/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/MessageFormatter.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/MessageFormatter.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/MessageFormatter.java
deleted file mode 100644
index e90eb65..0000000
--- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/MessageFormatter.java
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2006 The Apache Software Foundation
-//
-// 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.
-
-package org.apache.tapestry5.ioc;
-
-/**
- * Obtained from a {@link org.apache.tapestry5.ioc.Messages}, used to format messages for a specific localized message
- * key.
- */
-public interface MessageFormatter
-{
-    /**
-     * Formats the message. The arguments are passed to {@link java.util.Formatter} as is with one exception: Object of
-     * type {@link Throwable} are converted to their {@link Throwable#getMessage()} (or, if that is null, to the name of
-     * the class).
-     *
-     * @param args
-     * @return formatted string
-     */
-    String format(Object... args);
-}

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/f963c7ab/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/Messages.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/Messages.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/Messages.java
deleted file mode 100644
index ba7452c..0000000
--- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/Messages.java
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2006, 2007, 2012 The Apache Software Foundation
-//
-// 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.
-
-package org.apache.tapestry5.ioc;
-
-import java.util.Set;
-
-/**
- * Provides access to a messages catalog, a set of properties files that provide localized messages for a particular
- * locale. The message catalog consists of keys and values and follows the semantics of a Java {@link
- * java.util.ResourceBundle} with some changes.
- */
-public interface Messages
-{
-    /**
-     * Returns true if the bundle contains the named key.
-     */
-    boolean contains(String key);
-
-    /**
-     * Returns the localized message for the given key. If catalog does not contain such a key, then a modified version
-     * of the key is returned (converted to upper case and enclosed in brackets).
-     *
-     * @param key
-     * @return localized message for key, or placeholder
-     */
-    String get(String key);
-
-    /**
-     * Returns a formatter for the message, which can be used to substitute arguments (as per {@link
-     * java.util.Formatter}).
-     *
-     * @param key
-     * @return formattable object
-     */
-    MessageFormatter getFormatter(String key);
-
-    /**
-     * Convenience for accessing a formatter and formatting a localized message with arguments.
-     */
-    String format(String key, Object... args);
-
-    /**
-     * Returns a set of all the keys for which this instance may provide a value.
-     *
-     * @return set of keys
-     * @since 5.4
-     */
-    Set<String> getKeys();
-}