/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package freemarker.core;

import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;

import freemarker.cache.AndMatcher;
import freemarker.cache.ConditionalTemplateConfigurationFactory;
import freemarker.cache.FileExtensionMatcher;
import freemarker.cache.FileNameGlobMatcher;
import freemarker.cache.FirstMatchTemplateConfigurationFactory;
import freemarker.cache.MergingTemplateConfigurationFactory;
import freemarker.cache.NotMatcher;
import freemarker.cache.OrMatcher;
import freemarker.cache.PathGlobMatcher;
import freemarker.cache.PathRegexMatcher;
import freemarker.ext.beans.BeansWrapper;
import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.SimpleObjectWrapper;
import freemarker.template.TemplateHashModel;
import freemarker.template.TemplateMethodModelEx;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;
import freemarker.template.Version;
import freemarker.template.utility.ClassUtil;
import freemarker.template.utility.StringUtil;
import freemarker.template.utility.WriteProtectable;

/**
 * Don't use this; used internally by FreeMarker, might changes without notice.
 * 
 * Evaluates object builder expressions used in configuration {@link Properties}.
 * It should be replaced with FTL later (when it was improved to be practical for this), so the syntax should be
 * a subset of the future FTL syntax. This is also why this syntax is restrictive; it shouldn't accept anything that
 * FTL will not.
 */
// Java 5: use generics for expectedClass
// Java 5: Introduce ObjectBuilder interface
public class _ObjectBuilderSettingEvaluator {
    
    private static final String INSTANCE_FIELD_NAME = "INSTANCE";

    private static final String BUILD_METHOD_NAME = "build";

    private static final String BUILDER_CLASS_POSTFIX = "Builder";

    private static Map<String,String> SHORTHANDS;
    
    private static final Object VOID = new Object();

    private final String src;
    private final Class expectedClass;
    private final boolean allowNull;
    private final _SettingEvaluationEnvironment env;

    // Parser state:
    private int pos;
    
    // Parsing results:
    private boolean modernMode = false;
    
    private _ObjectBuilderSettingEvaluator(
            String src, int pos, Class expectedClass, boolean allowNull, _SettingEvaluationEnvironment env) {
        this.src = src;
        this.pos = pos;
        this.expectedClass = expectedClass;
        this.allowNull = allowNull;
        this.env = env;
    }

    public static Object eval(String src, Class expectedClass, boolean allowNull, _SettingEvaluationEnvironment env)
            throws _ObjectBuilderSettingEvaluationException,
            ClassNotFoundException, InstantiationException, IllegalAccessException {
        return new _ObjectBuilderSettingEvaluator(src, 0, expectedClass, allowNull, env).eval();
    }

    /**
     * Used for getting a list of setting assignments (like {@code (x=1, y=2)}) from an existing string, and apply it on
     * an existing bean.
     * 
     * @return The location of the next character to process.
     */
    public static int configureBean(
            String argumentListSrc, int posAfterOpenParen, Object bean, _SettingEvaluationEnvironment env)
            throws _ObjectBuilderSettingEvaluationException,
            ClassNotFoundException, InstantiationException, IllegalAccessException {
        return new _ObjectBuilderSettingEvaluator(
                argumentListSrc, posAfterOpenParen, bean.getClass(), true, env).configureBean(bean);
    }
    
    private Object eval() throws _ObjectBuilderSettingEvaluationException,
            ClassNotFoundException, InstantiationException, IllegalAccessException {
        Object value;
        
        skipWS();
        try {
            value = ensureEvaled(fetchValue(false, true, false, true));
        } catch (LegacyExceptionWrapperSettingEvaluationExpression e) {
            e.rethrowLegacy();
            value = null; // newer reached
        }
        skipWS();
        
        if (pos != src.length()) {
            throw new _ObjectBuilderSettingEvaluationException("end-of-expression", src, pos);
        }
        
        if (value == null && !allowNull) {
            throw new _ObjectBuilderSettingEvaluationException("Value can't be null.");
        }
        if (value != null && !expectedClass.isInstance(value)) {
            throw new _ObjectBuilderSettingEvaluationException("The resulting object (of class "
                    + value.getClass() + ") is not a(n) " + expectedClass.getName() + ".");
        }
        
        return value;
    }
    
    private int configureBean(Object bean) throws _ObjectBuilderSettingEvaluationException,
            ClassNotFoundException, InstantiationException, IllegalAccessException {
        final PropertyAssignmentsExpression propAssignments = new PropertyAssignmentsExpression(bean);
        fetchParameterListInto(propAssignments);
        skipWS();
        propAssignments.eval();
        return pos;
    }

    private Object ensureEvaled(Object value) throws _ObjectBuilderSettingEvaluationException {
        return value instanceof SettingExpression ? ((SettingExpression) value).eval() : value;
    }

    private Object fetchBuilderCall(boolean optional, boolean topLevel)
            throws _ObjectBuilderSettingEvaluationException {
        int startPos = pos;
        
        BuilderCallExpression exp = new BuilderCallExpression();
        // We need the canBeStaticField/mustBeStaticFiled complication to deal with legacy syntax where parentheses
        // weren't required for constructor calls.
        exp.canBeStaticField = true;
        
        final String fetchedClassName = fetchClassName(optional);
        {
            if (fetchedClassName == null) {
                if (!optional) {
                    throw new _ObjectBuilderSettingEvaluationException("class name", src, pos);
                }
                return VOID;
            }
            exp.className = shorthandToFullQualified(fetchedClassName);
            if (!fetchedClassName.equals(exp.className)) {
                // Before 2.3.21 only full-qualified class names were allowed
                modernMode = true;
                exp.canBeStaticField = false;
            }
        }
        
        skipWS();
        
        char openParen = fetchOptionalChar("(");
        // Only the top-level expression can omit the "(...)"
        if (openParen == 0 && !topLevel) {
            if (fetchedClassName.indexOf('.') != -1) {
                exp.mustBeStaticField = true;
            } else {
                pos = startPos;
                return VOID;
            }
        }
    
        if (openParen != 0) {
            fetchParameterListInto(exp);
            exp.canBeStaticField = false;
        }
        
        return exp;
    }

    private void fetchParameterListInto(ExpressionWithParameters exp) throws _ObjectBuilderSettingEvaluationException {
        // Before 2.3.21 there was no parameter list
        modernMode = true;
        
        skipWS();
        if (fetchOptionalChar(")") != ')') { 
            do {
                skipWS();
                
                Object paramNameOrValue = fetchValue(false, false, true, false);
                if (paramNameOrValue != VOID) {
                    skipWS();
                    if (paramNameOrValue instanceof Name) {
                        exp.namedParamNames.add(((Name) paramNameOrValue).name);
                        
                        skipWS();
                        fetchRequiredChar("=");
                        skipWS();
                        
                        Object paramValue = fetchValue(false, false, true, true);
                        exp.namedParamValues.add(ensureEvaled(paramValue));
                    } else {
                        if (!exp.namedParamNames.isEmpty()) {
                            throw new _ObjectBuilderSettingEvaluationException(
                                    "Positional parameters must precede named parameters");
                        }
                        if (!exp.getAllowPositionalParameters()) {
                            throw new _ObjectBuilderSettingEvaluationException(
                                    "Positional parameters not supported here");
                        }
                        exp.positionalParamValues.add(ensureEvaled(paramNameOrValue));
                    }
                    
                    skipWS();
                }
            } while (fetchRequiredChar(",)") == ',');
        }
    }

    private Object fetchValue(boolean optional, boolean topLevel, boolean resultCoerced, boolean resolveVariables)
            throws _ObjectBuilderSettingEvaluationException {
        if (pos < src.length()) {
            Object val = fetchNumberLike(true, resultCoerced);
            if (val != VOID) {
                return val;
            }
    
            val = fetchStringLiteral(true);
            if (val != VOID) {
                return val;
            }

            val = fetchListLiteral(true);
            if (val != VOID) {
                return val;
            }

            val = fetchMapLiteral(true);
            if (val != VOID) {
                return val;
            }
            
            val = fetchBuilderCall(true, topLevel);
            if (val != VOID) {
                return val;
            }
            
            String name = fetchSimpleName(true);
            if (name != null) {
                val = keywordToValueOrVoid(name);
                if (val != VOID) {
                    return val;
                }
                
                if (resolveVariables) {
                    // Not supported currently...
                    throw new _ObjectBuilderSettingEvaluationException("Can't resolve variable reference: " + name);
                } else {
                    return new Name(name);
                }
            }
        }
        
        if (optional) {
            return VOID;
        } else {
            throw new _ObjectBuilderSettingEvaluationException("value or name", src, pos);
        }
    }

    private boolean isKeyword(String name) {
        return keywordToValueOrVoid(name) != VOID;
    }
    
    private Object keywordToValueOrVoid(String name) {
        if (name.equals("true")) return Boolean.TRUE;
        if (name.equals("false")) return Boolean.FALSE;
        if (name.equals("null")) return null;
        return VOID;
    }

    private String fetchSimpleName(boolean optional) throws _ObjectBuilderSettingEvaluationException {
        char c = pos < src.length() ? src.charAt(pos) : 0;
        if (!isIdentifierStart(c)) {
            if (optional) {
                return null;
            } else {
                throw new _ObjectBuilderSettingEvaluationException("class name", src, pos);
            }
        }
        int startPos = pos;
        pos++;
        
        seekClassNameEnd: while (true) {
            if (pos == src.length()) {
                break seekClassNameEnd;
            }
            c = src.charAt(pos);
            if (!isIdentifierMiddle(c)) {
                break seekClassNameEnd;
            }
            pos++;
        }
        
        return src.substring(startPos, pos);
    }

    private String fetchClassName(boolean optional) throws _ObjectBuilderSettingEvaluationException {
        int startPos = pos;
        StringBuilder sb = new StringBuilder();
        do {
            String name = fetchSimpleName(true);
            if (name == null) {
                if (!optional) {
                    throw new _ObjectBuilderSettingEvaluationException("name", src, pos);
                } else {
                    pos = startPos;
                    return null;
                }
            }
            sb.append(name);
            
            skipWS();
            
            if (pos >= src.length() || src.charAt(pos) != '.') {
                break;
            }
            sb.append('.');
            pos++;
            
            skipWS();
        } while (true);
        
        String className = sb.toString();
        if (isKeyword(className)) {
            pos = startPos;
            return null;
        }
        return className;
    }

    private Object fetchNumberLike(boolean optional, boolean resultCoerced)
            throws _ObjectBuilderSettingEvaluationException {
        int startPos = pos;
        boolean isVersion = false;
        boolean hasDot = false;
        seekTokenEnd: while (true) {
            if (pos == src.length()) {
                break seekTokenEnd;
            }
            char c = src.charAt(pos);
            if (c == '.') {
                if (hasDot) {
                    // More than one dot
                    isVersion = true;
                } else {
                    hasDot = true;
                }
            } else if (!(isASCIIDigit(c) || c == '-')) {
                break seekTokenEnd;
            }
            pos++;
        }
        
        if (startPos == pos) {
            if (optional) {
                return VOID;
            } else {
                throw new _ObjectBuilderSettingEvaluationException("number-like", src, pos);
            }
        }
        
        String numStr = src.substring(startPos, pos);
        if (isVersion) {
            try {
                return new Version(numStr);
            } catch (IllegalArgumentException e) {
                throw new _ObjectBuilderSettingEvaluationException("Malformed version number: " + numStr, e);
            }
        } else {
            // For example, in 1.0f, numStr is "1.0", and typePostfix is "f".
            String typePostfix = null;
            seekTypePostfixEnd: while (true) {
                if (pos == src.length()) {
                    break seekTypePostfixEnd;
                }
                char c = src.charAt(pos);
                if (Character.isLetter(c)) {
                    if (typePostfix == null) {
                        typePostfix = String.valueOf(c);
                    } else {
                        typePostfix += c; 
                    }
                } else {
                    break seekTypePostfixEnd;
                }
                pos++;
            }
            
            try {
                if (numStr.endsWith(".")) {
                    throw new NumberFormatException("A number can't end with a dot");
                }
                if (numStr.startsWith(".") || numStr.startsWith("-.")  || numStr.startsWith("+.")) {
                    throw new NumberFormatException("A number can't start with a dot");
                }

                if (typePostfix == null) {
                    // Auto-detect type
                    if (numStr.indexOf('.') == -1) {
                        BigInteger biNum = new BigInteger(numStr);
                        final int bitLength = biNum.bitLength();  // Doesn't include sign bit
                        if (bitLength <= 31) {
                            return Integer.valueOf(biNum.intValue());
                        } else if (bitLength <= 63) {
                            return Long.valueOf(biNum.longValue());
                        } else {
                            return biNum;
                        }
                    } else {
                        if (resultCoerced) {
                            // The FTL way (BigDecimal is loseless, and it will be coerced to the target type later):
                            return new BigDecimal(numStr);
                        } else {
                            // The Java way (lossy but familiar):
                            return Double.valueOf(numStr);
                        }
                    }
                } else { // Has explicitly specified type
                    if (typePostfix.equalsIgnoreCase("l")) {
                        return Long.valueOf(numStr);
                    } else if (typePostfix.equalsIgnoreCase("bi")) {
                        return new BigInteger(numStr);
                    } else if (typePostfix.equalsIgnoreCase("bd")) {
                        return new BigDecimal(numStr);
                    } else if (typePostfix.equalsIgnoreCase("d")) {
                        return Double.valueOf(numStr);
                    } else if (typePostfix.equalsIgnoreCase("f")) {
                        return Float.valueOf(numStr);
                    } else {
                        throw new _ObjectBuilderSettingEvaluationException(
                                "Unrecognized number type postfix: " + typePostfix);
                    }
                }
                
            } catch (NumberFormatException e) {
                throw new _ObjectBuilderSettingEvaluationException("Malformed number: " + numStr, e);
            }
        }
    }

    private Object fetchStringLiteral(boolean optional) throws _ObjectBuilderSettingEvaluationException {
        int startPos = pos;
        char q = 0;
        boolean afterEscape = false;
        boolean raw = false;
        seekTokenEnd: while (true) {
            if (pos == src.length()) {
                if (q != 0) {
                    // We had an open quotation
                    throw new _ObjectBuilderSettingEvaluationException(String.valueOf(q), src, pos);
                }
                break seekTokenEnd;
            }
            char c = src.charAt(pos);
            if (q == 0) {
                if (c == 'r' && (pos + 1 < src.length())) {
                    // Maybe it's like r"foo\bar"
                    raw = true;
                    c = src.charAt(pos + 1);
                }
                if (c == '\'') {
                    q = '\'';
                } else if (c == '"') {
                    q = '"';
                } else {
                    break seekTokenEnd;
                }
                if (raw) {
                    // because of the preceding "r"
                    pos++;
                }
            } else {
                if (!afterEscape) {
                    if (c == '\\' && !raw) {
                        afterEscape = true;
                    } else if (c == q) {
                        break seekTokenEnd;
                    } else if (c == '{') {
                        char prevC = src.charAt(pos - 1);
                        if (prevC == '$' || prevC == '#') {
                            throw new _ObjectBuilderSettingEvaluationException(
                                    "${...} and #{...} aren't allowed here.");
                        }
                    }
                } else {
                    afterEscape = false;
                }
            }
            pos++;
        }
        if (startPos == pos) {
            if (optional) {
                return VOID;
            } else {
                throw new _ObjectBuilderSettingEvaluationException("string literal", src, pos);
            }
        }
            
        final String sInside = src.substring(startPos + (raw ? 2 : 1), pos);
        try {
            pos++; // skip closing quotation mark
            return raw ? sInside : StringUtil.FTLStringLiteralDec(sInside);
        } catch (ParseException e) {
            throw new _ObjectBuilderSettingEvaluationException("Malformed string literal: " + sInside, e);
        }
    }

    private Object fetchListLiteral(boolean optional) throws _ObjectBuilderSettingEvaluationException {
        if (pos == src.length() || src.charAt(pos) != '[') {
            if (!optional) {
                throw new _ObjectBuilderSettingEvaluationException("[", src, pos);
            }
            return VOID;
        }
        pos++;
        
        ListExpression listExp = new ListExpression();
        
        while (true) {
            skipWS();
            
            if (fetchOptionalChar("]") != 0) {
                return listExp;
            }
            if (listExp.itemCount() != 0) {
                fetchRequiredChar(",");
                skipWS();
            }
            
            listExp.addItem(fetchValue(false, false, false, true));
            
            skipWS();
        }
    }

    private Object fetchMapLiteral(boolean optional) throws _ObjectBuilderSettingEvaluationException {
        if (pos == src.length() || src.charAt(pos) != '{') {
            if (!optional) {
                throw new _ObjectBuilderSettingEvaluationException("{", src, pos);
            }
            return VOID;
        }
        pos++;
        
        MapExpression mapExp = new MapExpression();
        
        while (true) {
            skipWS();
            
            if (fetchOptionalChar("}") != 0) {
                return mapExp;
            }
            if (mapExp.itemCount() != 0) {
                fetchRequiredChar(",");
                skipWS();
            }
            
            Object key = fetchValue(false, false, false, true);
            skipWS();
            fetchRequiredChar(":");
            skipWS();
            Object value = fetchValue(false, false, false, true);
            mapExp.addItem(new KeyValuePair(key, value));
            
            skipWS();
        }
    }
    
    private void skipWS() {
        while (true) {
            if (pos == src.length()) {
                return;
            }
            char c = src.charAt(pos);
            if (!Character.isWhitespace(c)) {
                return;
            }
            pos++;
        }
    }

    private char fetchOptionalChar(String expectedChars) throws _ObjectBuilderSettingEvaluationException {
        return fetchChar(expectedChars, true);
    }
    
    private char fetchRequiredChar(String expectedChars) throws _ObjectBuilderSettingEvaluationException {
        return fetchChar(expectedChars, false);
    }
    
    private char fetchChar(String expectedChars, boolean optional) throws _ObjectBuilderSettingEvaluationException {
        char c = pos < src.length() ? src.charAt(pos) : 0;
        if (expectedChars.indexOf(c) != -1) {
            pos++;
            return c;
        } else if (optional) {
            return 0;
        } else {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < expectedChars.length(); i++) {
                if (i != 0) {
                    sb.append(" or ");
                }
                sb.append(StringUtil.jQuote(expectedChars.substring(i, i + 1)));
            }
            throw new _ObjectBuilderSettingEvaluationException(
                    sb.toString(),
                    src, pos);
        }
    }
    
    private boolean isASCIIDigit(char c) {
        return c >= '0' && c <= '9';
    }

    private boolean isIdentifierStart(char c) {
        return Character.isLetter(c) || c == '_' || c == '$';
    }

    private boolean isIdentifierMiddle(char c) {
        return isIdentifierStart(c) || isASCIIDigit(c);
    }

    private static synchronized String shorthandToFullQualified(String className) {
        if (SHORTHANDS == null) {
            SHORTHANDS = new HashMap/*<String,String>*/();
            
            addWithSimpleName(SHORTHANDS, DefaultObjectWrapper.class);
            addWithSimpleName(SHORTHANDS, BeansWrapper.class);
            addWithSimpleName(SHORTHANDS, SimpleObjectWrapper.class);

            addWithSimpleName(SHORTHANDS, TemplateConfiguration.class);
            
            addWithSimpleName(SHORTHANDS, PathGlobMatcher.class);
            addWithSimpleName(SHORTHANDS, FileNameGlobMatcher.class);
            addWithSimpleName(SHORTHANDS, FileExtensionMatcher.class);
            addWithSimpleName(SHORTHANDS, PathRegexMatcher.class);
            addWithSimpleName(SHORTHANDS, AndMatcher.class);
            addWithSimpleName(SHORTHANDS, OrMatcher.class);
            addWithSimpleName(SHORTHANDS, NotMatcher.class);
            
            addWithSimpleName(SHORTHANDS, ConditionalTemplateConfigurationFactory.class);
            addWithSimpleName(SHORTHANDS, MergingTemplateConfigurationFactory.class);
            addWithSimpleName(SHORTHANDS, FirstMatchTemplateConfigurationFactory.class);

            addWithSimpleName(SHORTHANDS, HTMLOutputFormat.class);
            addWithSimpleName(SHORTHANDS, XMLOutputFormat.class);
            addWithSimpleName(SHORTHANDS, RTFOutputFormat.class);
            addWithSimpleName(SHORTHANDS, PlainTextOutputFormat.class);
            addWithSimpleName(SHORTHANDS, UndefinedOutputFormat.class);
            
            addWithSimpleName(SHORTHANDS, Locale.class);
            SHORTHANDS.put("TimeZone", "freemarker.core._TimeZone");

            // For accessing static fields:
            addWithSimpleName(SHORTHANDS, Configuration.class);
        }
        String fullClassName = SHORTHANDS.get(className);
        return fullClassName == null ? className : fullClassName;
    }
    
    private static void addWithSimpleName(Map map, Class<?> pClass) {
        map.put(pClass.getSimpleName(), pClass.getName());
    }

    private void setJavaBeanProperties(Object bean,
            List/*<String>*/ namedParamNames, List/*<Object>*/ namedParamValues)
            throws _ObjectBuilderSettingEvaluationException {
        if (namedParamNames.isEmpty()) {
            return;
        }
        
        final Class cl = bean.getClass();
        Map/*<String,Method>*/ beanPropSetters;
        try {
            PropertyDescriptor[] propDescs = Introspector.getBeanInfo(cl).getPropertyDescriptors();
            beanPropSetters = new HashMap(propDescs.length * 4 / 3, 1.0f);
            for (int i = 0; i < propDescs.length; i++) {
                PropertyDescriptor propDesc = propDescs[i];
                final Method writeMethod = propDesc.getWriteMethod();
                if (writeMethod != null) {
                    beanPropSetters.put(propDesc.getName(), writeMethod);
                }
            }
        } catch (Exception e) {
            throw new _ObjectBuilderSettingEvaluationException("Failed to inspect " + cl.getName() + " class", e);
        }

        TemplateHashModel beanTM = null;
        for (int i = 0; i < namedParamNames.size(); i++) {
            String name = (String) namedParamNames.get(i);
            if (!beanPropSetters.containsKey(name)) {
                throw new _ObjectBuilderSettingEvaluationException(
                        "The " + cl.getName() + " class has no writeable JavaBeans property called "
                        + StringUtil.jQuote(name) + ".");
            }
            
            Method beanPropSetter = (Method) beanPropSetters.put(name, null);
            if (beanPropSetter == null) {
                    throw new _ObjectBuilderSettingEvaluationException(
                            "JavaBeans property " + StringUtil.jQuote(name) + " is set twice.");
            }
            
            try {
                if (beanTM == null) {
                    TemplateModel wrappedObj = env.getObjectWrapper().wrap(bean);
                    if (!(wrappedObj instanceof TemplateHashModel)) {
                        throw new _ObjectBuilderSettingEvaluationException(
                                "The " + cl.getName() + " class is not a wrapped as TemplateHashModel.");
                    }
                    beanTM = (TemplateHashModel) wrappedObj;
                }
                
                TemplateModel m = beanTM.get(beanPropSetter.getName());
                if (m == null) {
                    throw new _ObjectBuilderSettingEvaluationException(
                            "Can't find " + beanPropSetter + " as FreeMarker method.");
                }
                if (!(m instanceof TemplateMethodModelEx)) {
                    throw new _ObjectBuilderSettingEvaluationException(
                            StringUtil.jQuote(beanPropSetter.getName()) + " wasn't a TemplateMethodModelEx.");
                }
                List/*TemplateModel*/ args = new ArrayList();
                args.add(env.getObjectWrapper().wrap(namedParamValues.get(i)));
                ((TemplateMethodModelEx) m).exec(args);
            } catch (Exception e) {
                throw new _ObjectBuilderSettingEvaluationException(
                        "Failed to set " + StringUtil.jQuote(name), e);
            }
        }
    }

    private static class Name {
        
        public Name(String name) {
            this.name = name;
        }

        private final String name;
    }
    
    private abstract static class SettingExpression {
        abstract Object eval() throws _ObjectBuilderSettingEvaluationException;
    }
    
    private abstract class ExpressionWithParameters extends SettingExpression {
        protected List positionalParamValues = new ArrayList();
        protected List/*<String>*/ namedParamNames = new ArrayList();
        protected List/*<Object>*/ namedParamValues = new ArrayList();
        
        protected abstract boolean getAllowPositionalParameters();
    }
    
    private class ListExpression extends SettingExpression {
        
        private List<Object> items = new ArrayList();
        
        void addItem(Object item) {
            items.add(item);
        }

        public int itemCount() {
            return items.size();
        }

        @Override
        Object eval() throws _ObjectBuilderSettingEvaluationException {
            ArrayList res = new ArrayList(items.size());
            for (Object item : items) {
                res.add(ensureEvaled(item));
            }
            return res;
        }
        
    }
    
    private class MapExpression extends SettingExpression {
        
        private List<KeyValuePair> items = new ArrayList();
        
        void addItem(KeyValuePair item) {
            items.add(item);
        }

        public int itemCount() {
            return items.size();
        }

        @Override
        Object eval() throws _ObjectBuilderSettingEvaluationException {
            LinkedHashMap res = new LinkedHashMap(items.size() * 4 / 3, 1f);
            for (KeyValuePair item : items) {
                Object key = ensureEvaled(item.key);
                if (key == null) {
                    throw new _ObjectBuilderSettingEvaluationException("Map can't use null as key.");
                }
                res.put(key, ensureEvaled(item.value));
            }
            return res;
        }
        
    }
    
    private static class KeyValuePair {
        private final Object key;
        private final Object value;
        
        public KeyValuePair(Object key, Object value) {
            this.key = key;
            this.value = value;
        }
    }
    
    private class BuilderCallExpression extends ExpressionWithParameters {
        private String className;
        private boolean canBeStaticField;
        private boolean mustBeStaticField;
        
        @Override
        Object eval() throws _ObjectBuilderSettingEvaluationException {
            if (mustBeStaticField) {
                if (!canBeStaticField) {
                    throw new BugException();
                }
                return getStaticFieldValue(className);
            }
            
            Class cl;
            
            if (!modernMode) {
                try {
                    try {
                        return ClassUtil.forName(className).newInstance();
                    } catch (InstantiationException e) {
                        throw new LegacyExceptionWrapperSettingEvaluationExpression(e);
                    } catch (IllegalAccessException e) {
                        throw new LegacyExceptionWrapperSettingEvaluationExpression(e);
                    } catch (ClassNotFoundException e) {
                        throw new LegacyExceptionWrapperSettingEvaluationExpression(e);
                    }
                } catch (LegacyExceptionWrapperSettingEvaluationExpression e) {
                    if (!canBeStaticField) {
                        throw e;
                    }
                    // Silently try to interpret className as static filed, throw the original exception if that fails. 
                    try {
                        return getStaticFieldValue(className);
                    } catch (_ObjectBuilderSettingEvaluationException e2) {
                        throw e;
                    }
                }
            }

            boolean clIsBuilderClass;
            try {
                cl = ClassUtil.forName(className + BUILDER_CLASS_POSTFIX);
                clIsBuilderClass = true;
            } catch (ClassNotFoundException e) {
                clIsBuilderClass = false;
                try {
                    cl = ClassUtil.forName(className);
                } catch (Exception e2) {
                    boolean failedToGetAsStaticField;
                    if (canBeStaticField) {
                        // Try to interpret className as static filed: 
                        try {
                            return getStaticFieldValue(className);
                        } catch (_ObjectBuilderSettingEvaluationException e3) {
                            // Suppress it
                            failedToGetAsStaticField = true;
                        }
                    } else {
                        failedToGetAsStaticField = false;
                    }
                    throw new _ObjectBuilderSettingEvaluationException(
                            "Failed to get class " + StringUtil.jQuote(className)
                            + (failedToGetAsStaticField ? " (also failed to resolve name as static field)" : "")
                            + ".",
                            e2);
                }
            }
            
            if (!clIsBuilderClass && hasNoParameters()) {
                try {
                    Field f = cl.getField(INSTANCE_FIELD_NAME);
                    if ((f.getModifiers() & (Modifier.PUBLIC | Modifier.STATIC))
                            == (Modifier.PUBLIC | Modifier.STATIC)) {
                        return f.get(null);
                    }
                } catch (NoSuchFieldException e) {
                    // Expected
                } catch (Exception e) {
                    throw new _ObjectBuilderSettingEvaluationException(
                            "Error when trying to access " + StringUtil.jQuote(className) + "."
                            + INSTANCE_FIELD_NAME, e);
                }
            }
            
            // Create the object to return or its builder:
            Object constructorResult = callConstructor(cl);
            
            // Named parameters will set JavaBeans properties:
            setJavaBeanProperties(constructorResult, namedParamNames, namedParamValues);

            final Object result;
            if (clIsBuilderClass) {
                result = callBuild(constructorResult);
            } else {
                if (constructorResult instanceof WriteProtectable) {
                    ((WriteProtectable) constructorResult).writeProtect();
                }
                result = constructorResult;
            }
            
            return result;
        }
        
        private Object getStaticFieldValue(String dottedName) throws _ObjectBuilderSettingEvaluationException {
            int lastDotIdx = dottedName.lastIndexOf('.');
            if (lastDotIdx == -1) {
                throw new IllegalArgumentException();
            }
            String className = shorthandToFullQualified(dottedName.substring(0, lastDotIdx));
            String fieldName = dottedName.substring(lastDotIdx + 1);

            Class<?> cl;
            try {
                cl = ClassUtil.forName(className);
            } catch (Exception e) {
                throw new _ObjectBuilderSettingEvaluationException(
                        "Failed to get field's parent class, " + StringUtil.jQuote(className) + ".",
                        e);
            }
            
            Field field;
            try {
                field = cl.getField(fieldName);
            } catch (Exception e) {
                throw new _ObjectBuilderSettingEvaluationException(
                        "Failed to get field " + StringUtil.jQuote(fieldName) + " from class "
                        + StringUtil.jQuote(className) + ".",
                        e);
            }
            
            if ((field.getModifiers() & Modifier.STATIC) == 0) {
                throw new _ObjectBuilderSettingEvaluationException("Referred field isn't static: " + field);
            }
            if ((field.getModifiers() & Modifier.PUBLIC) == 0) {
                throw new _ObjectBuilderSettingEvaluationException("Referred field isn't public: " + field);
            }

            if (field.getName().equals(INSTANCE_FIELD_NAME)) {
                throw new _ObjectBuilderSettingEvaluationException(
                        "The " + INSTANCE_FIELD_NAME + " field is only accessible through pseudo-constructor call: "
                        + className + "()");
            }
            
            try {
                return field.get(null);
            } catch (Exception e) {
                throw new _ObjectBuilderSettingEvaluationException("Failed to get field value: " + field, e);
            }
        }

        private Object callConstructor(Class cl)
                throws _ObjectBuilderSettingEvaluationException {
            if (hasNoParameters()) {
                // No need to create ObjectWrapper
                try {
                    return cl.newInstance();
                } catch (Exception e) {
                    throw new _ObjectBuilderSettingEvaluationException(
                            "Failed to call " + cl.getName() + " 0-argument constructor", e);
                }
            } else {
                BeansWrapper ow = env.getObjectWrapper();
                List/*<TemplateModel>*/ tmArgs = new ArrayList(positionalParamValues.size());
                for (int i = 0; i < positionalParamValues.size(); i++) {
                    try {
                        tmArgs.add(ow.wrap(positionalParamValues.get(i)));
                    } catch (TemplateModelException e) {
                        throw new _ObjectBuilderSettingEvaluationException("Failed to wrap arg #" + (i + 1), e);
                    }
                }
                try {
                    return ow.newInstance(cl, tmArgs);
                } catch (Exception e) {
                    throw new _ObjectBuilderSettingEvaluationException(
                            "Failed to call " + cl.getName() + " constructor", e);
                }
            }
        }

        private Object callBuild(Object constructorResult)
                throws _ObjectBuilderSettingEvaluationException {
            final Class cl = constructorResult.getClass();
            Method buildMethod; 
            try {
                buildMethod = constructorResult.getClass().getMethod(BUILD_METHOD_NAME, (Class[]) null);
            } catch (NoSuchMethodException e) {
                throw new _ObjectBuilderSettingEvaluationException("The " + cl.getName()
                        + " builder class must have a public " + BUILD_METHOD_NAME + "() method", e);
            } catch (Exception e) {
                throw new _ObjectBuilderSettingEvaluationException("Failed to get the " + BUILD_METHOD_NAME
                        + "() method of the " + cl.getName() + " builder class", e);
            }
            
            try {
                return buildMethod.invoke(constructorResult, (Object[]) null);
            } catch (Exception e) {
                Throwable cause;
                if (e instanceof InvocationTargetException) {
                    cause = ((InvocationTargetException) e).getTargetException();
                } else {
                    cause = e;
                }
                throw new _ObjectBuilderSettingEvaluationException("Failed to call " + BUILD_METHOD_NAME
                        + "() method on " + cl.getName() + " instance", cause);
            }
        }

        private boolean hasNoParameters() {
            return positionalParamValues.isEmpty() && namedParamValues.isEmpty();
        }

        @Override
        protected boolean getAllowPositionalParameters() {
            return true;
        }
        
    }
    
    private class PropertyAssignmentsExpression extends ExpressionWithParameters {
        
        private final Object bean;
        
        public PropertyAssignmentsExpression(Object bean) {
            this.bean = bean;
        }

        @Override
        Object eval() throws _ObjectBuilderSettingEvaluationException {
            setJavaBeanProperties(bean, namedParamNames, namedParamValues);
            return bean;
        }

        @Override
        protected boolean getAllowPositionalParameters() {
            return false;
        }
        
    }
    
    private static class LegacyExceptionWrapperSettingEvaluationExpression
            extends _ObjectBuilderSettingEvaluationException {

        public LegacyExceptionWrapperSettingEvaluationExpression(Throwable cause) {
            super("Legacy operation failed", cause);
            if (!(
                    (cause instanceof ClassNotFoundException) 
                    || (cause instanceof InstantiationException)
                    || (cause instanceof IllegalAccessException)
                    )) {
                throw new IllegalArgumentException();
            }
        }

        public void rethrowLegacy() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
            Throwable cause = getCause();
            if (cause instanceof ClassNotFoundException) throw (ClassNotFoundException) cause;
            if (cause instanceof InstantiationException) throw (InstantiationException) cause;
            if (cause instanceof IllegalAccessException) throw (IllegalAccessException) cause;
            throw new BugException();
        }
        
    }
    
}
