/*
 * Copyright 2006-2016 the original author or authors.
 *
 * 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 com.consol.citrus.context;

import java.util.Map;

import com.consol.citrus.exceptions.CitrusRuntimeException;
import com.consol.citrus.spi.ReferenceResolver;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

/**
 * Spring bean reference resolver operates on given application context to resolve bean references.
 *
 * @author Christoph Deppisch
 * @since 2.5
 */
public class SpringBeanReferenceResolver implements ReferenceResolver, ApplicationContextAware {

    private ApplicationContext applicationContext;

    /**
     * Default constructor.
     */
    public SpringBeanReferenceResolver() {
        super();
    }

    /**
     * Constructor initializes with given application context.
     * @param applicationContext
     */
    public SpringBeanReferenceResolver(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

    @Override
    public <T> T resolve(Class<T> requiredType) {
        try {
            return applicationContext.getBean(requiredType);
        } catch (NoSuchBeanDefinitionException e) {
            throw new CitrusRuntimeException(String.format("Unable to find bean reference for type '%s'", requiredType), e);
        }
    }

    @Override
    public <T> T resolve(String name, Class<T> type) {
        try {
            return applicationContext.getBean(name, type);
        } catch (NoSuchBeanDefinitionException e) {
            throw new CitrusRuntimeException(String.format("Unable to find bean reference for name '%s'", name), e);
        }
    }

    @Override
    public Object resolve(String name) {
        try {
            return applicationContext.getBean(name);
        } catch (NoSuchBeanDefinitionException e) {
            throw new CitrusRuntimeException(String.format("Unable to find bean reference for name '%s'", name), e);
        }
    }

    @Override
    public <T> Map<String, T> resolveAll(Class<T> requiredType) {
        try {
            return applicationContext.getBeansOfType(requiredType);
        } catch (NoSuchBeanDefinitionException e) {
            throw new CitrusRuntimeException(String.format("Unable to find bean references for type '%s'", requiredType), e);
        }
    }

    @Override
    public boolean isResolvable(String name) {
        return applicationContext.containsBean(name);
    }

    @Override
    public void bind(String name, Object value) {
        throw new UnsupportedOperationException("Spring bean reference resolver does not support manual reference bindings - " +
                "please add proper bean reference to the Spring application context instead");
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    /**
     * Obtains the applicationContext.
     * @return
     */
    public ApplicationContext getApplicationContext() {
        return applicationContext;
    }
}

@@ -781,16 +781,70 @@
 solver;%0A
+import com.consol.citrus.spi.SimpleReferenceResolver;%0A
 import o
@@ -1377,16 +1377,95 @@
 ntext;%0A%0A
+    private SimpleReferenceResolver fallback = new SimpleReferenceResolver();%0A%0A
     /**%0A
@@ -2339,32 +2339,146 @@
 nException e) %7B%0A
+            if (fallback.isResolvable(name)) %7B%0A                return fallback.resolve(name, type);%0A            %7D%0A
             thro
@@ -2761,32 +2761,140 @@
 nException e) %7B%0A
+            if (fallback.isResolvable(name)) %7B%0A                return fallback.resolve(name);%0A            %7D%0A
             thro
@@ -3477,24 +3477,55 @@
 nsBean(name)
+ %7C%7C fallback.isResolvable(name)
 ;%0A    %7D%0A%0A   
@@ -3597,221 +3597,33 @@
     
-throw new UnsupportedOperationException(%22Spring bean reference resolver does not support manual reference bindings - %22 +%0A                %22please add proper bean reference to the Spring application context instead%22
+fallback.bind(name, value
 );%0A 

Add simple reference resolver fallback