private synchronized Template buildAndRegister(TemplateBuilder builder,
            final Class targetClass, final boolean hasAnnotation,
            final FieldList flist) {
        Template newTmpl = null;
        Template oldTmpl = null;
        try {
            if (cache.containsKey(targetClass)) {
                oldTmpl = cache.get(targetClass);
            }
            newTmpl = new TemplateReference(this, targetClass);
            cache.put(targetClass, newTmpl);
            if (builder == null) {
                builder = chain.select(targetClass, hasAnnotation);
            }
            newTmpl = flist != null ?
                    builder.buildTemplate(targetClass, flist) : builder.buildTemplate(targetClass);
            return newTmpl;
        } catch (Exception e) {
            if (oldTmpl != null) {
                cache.put(targetClass, oldTmpl);
            } else {
                cache.remove(targetClass);
            }
            newTmpl = null;
            if (e instanceof MessageTypeException) {
                throw (MessageTypeException) e;
            } else {
                throw new MessageTypeException(e);
            }
        } finally {
            if (newTmpl != null) {
                cache.put(targetClass, newTmpl);
            }
        }
    }