// Path: repository/src/main/java/de/acosix/alfresco/mtsupport/repo/beans/TenantBeanUtils.java
// public final class TenantBeanUtils
// {
// 
//     public static final String TENANT_BEAN_NAME_PATTERN = ".tenant-";
// 
//     public static final String TENANT_BEAN_TEMPLATE_SUFFIX = ".template";
// 
//     public static final String TENANT_PLACEHOLDER = "tenant";
// 
//     public static final String TENANT_PLACEHOLDER_IN_PLACEHOLDER = ".thisTenant.";
// 
//     private TenantBeanUtils()
//     {
//         // NO-OP
//     }
// 
//     /**
//      * Retrieves a specific bean for a specific tenant from the provided application context. This operation should only be used when each
//      * tenant domain is backed by its own implementation bean for a feature and calls need to be delegated according to the tenant domain.
//      *
//      * @param applicationContext
//      *            the application context from which to retrieve the bean
//      * @param baseBeanName
//      *            the base bean name
//      * @param tenantDomain
//      *            the tenant domain for which to retrieve the bean
//      * @return the bean
//      */
//     public static Object getBeanForTenant(final ApplicationContext applicationContext, final String baseBeanName, final String tenantDomain)
//     {
//         ParameterCheck.mandatory("applicationContext", applicationContext);
//         ParameterCheck.mandatoryString("baseBeanName", baseBeanName);
//         ParameterCheck.mandatoryString("tenantDomain", tenantDomain);
// 
//         final String expectedBeanName = baseBeanName + TENANT_BEAN_NAME_PATTERN + tenantDomain;
//         final Object bean = applicationContext.getBean(expectedBeanName);
//         return bean;
//     }
// 
//     /**
//      * Retrieves a specific bean definition for a specific tenant from the provided registry. This operation should only be used when each
//      * tenant domain is backed by its own implementation bean for a feature.
//      *
//      * @param registry
//      *            the bean definition registry from which to retrieve the bean definition
//      * @param baseBeanName
//      *            the base bean name
//      * @param tenantDomain
//      *            the tenant domain for which to retrieve the bean definition
//      * @return the bean definition
//      */
//     public static BeanDefinition getBeanDefinitionForTenant(final BeanDefinitionRegistry registry, final String baseBeanName,
//             final String tenantDomain)
//     {
//         ParameterCheck.mandatory("registry", registry);
//         ParameterCheck.mandatoryString("baseBeanName", baseBeanName);
//         ParameterCheck.mandatoryString("tenantDomain", tenantDomain);
// 
//         final String expectedBeanName = baseBeanName + TENANT_BEAN_NAME_PATTERN + tenantDomain;
//         final BeanDefinition beanDefinition = registry.getBeanDefinition(expectedBeanName);
//         return beanDefinition;
//     }
// 
//     /**
//      * Retrieves a specific bean for a specific tenant from the provided application context. This operation should only be used when each
//      * tenant domain is backed by its own implementation bean for a feature and calls need to be delegated according to the tenant domain.
//      *
//      * @param applicationContext
//      *            the application context from which to retrieve the bean
//      * @param baseBeanName
//      *            the base bean name
//      * @param tenantDomain
//      *            the tenant domain for which to retrieve the bean
//      * @param expectedType
//      *            the expected class or interface to which the bean must conform
//      * @return the bean
//      */
//     public static <T> T getBeanForTenant(final ApplicationContext applicationContext, final String baseBeanName, final String tenantDomain,
//             final Class<T> expectedType)
//     {
//         ParameterCheck.mandatory("applicationContext", applicationContext);
//         ParameterCheck.mandatoryString("baseBeanName", baseBeanName);
//         ParameterCheck.mandatoryString("tenantDomain", tenantDomain);
//         ParameterCheck.mandatory("expectedType", expectedType);
// 
//         final String expectedBeanName = baseBeanName + TENANT_BEAN_NAME_PATTERN + tenantDomain;
//         final T bean = applicationContext.getBean(expectedBeanName, expectedType);
//         return bean;
//     }
// }


import java.util.Properties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionVisitor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.beans.factory.config.TypedStringValue;
import org.springframework.util.StringValueResolver;
import de.acosix.alfresco.mtsupport.repo.beans.TenantBeanUtils;
                    final TypedStringValue typedStringValue = (TypedStringValue) value;
                    final String stringValue = typedStringValue.getValue();
                    if (stringValue != null)
                    {
                        final String visitedString = this.resolveStringValue(stringValue);
                        if (!stringValue.equals(visitedString))
                        {
                            result = typedStringValue.hasTargetType()
                                    ? new TypedStringValue(visitedString, typedStringValue.getTargetType())
                                    : new TypedStringValue(visitedString);
                        }
                    }
                }
                else
                {
                    result = super.resolveValue(value);
                }

                return result;
            }
        };

        final String[] beanNames = beanFactoryToProcess.getBeanDefinitionNames();
        for (final String curName : beanNames)
        {
            // Check that we're not parsing our own bean definition,
            // to avoid failing on unresolvable placeholders in properties file locations.
            if (!(curName.equals(this.beanName) && beanFactoryToProcess.equals(this.beanFactory)))
            {
                final String tenantDomain;
// Path: repository/src/main/java/de/acosix/alfresco/mtsupport/repo/beans/TenantBeanUtils.java
// public final class TenantBeanUtils
// {
// 
//     public static final String TENANT_BEAN_NAME_PATTERN = ".tenant-";
// 
//     public static final String TENANT_BEAN_TEMPLATE_SUFFIX = ".template";
// 
//     public static final String TENANT_PLACEHOLDER = "tenant";
// 
//     public static final String TENANT_PLACEHOLDER_IN_PLACEHOLDER = ".thisTenant.";
// 
//     private TenantBeanUtils()
//     {
//         // NO-OP
//     }
// 
//     /**
//      * Retrieves a specific bean for a specific tenant from the provided application context. This operation should only be used when each
//      * tenant domain is backed by its own implementation bean for a feature and calls need to be delegated according to the tenant domain.
//      *
//      * @param applicationContext
//      *            the application context from which to retrieve the bean
//      * @param baseBeanName
//      *            the base bean name
//      * @param tenantDomain
//      *            the tenant domain for which to retrieve the bean
//      * @return the bean
//      */
//     public static Object getBeanForTenant(final ApplicationContext applicationContext, final String baseBeanName, final String tenantDomain)
//     {
//         ParameterCheck.mandatory("applicationContext", applicationContext);
//         ParameterCheck.mandatoryString("baseBeanName", baseBeanName);
//         ParameterCheck.mandatoryString("tenantDomain", tenantDomain);
// 
//         final String expectedBeanName = baseBeanName + TENANT_BEAN_NAME_PATTERN + tenantDomain;
//         final Object bean = applicationContext.getBean(expectedBeanName);
//         return bean;
//     }
// 
//     /**
//      * Retrieves a specific bean definition for a specific tenant from the provided registry. This operation should only be used when each
//      * tenant domain is backed by its own implementation bean for a feature.
//      *
//      * @param registry
//      *            the bean definition registry from which to retrieve the bean definition
//      * @param baseBeanName
//      *            the base bean name
//      * @param tenantDomain
//      *            the tenant domain for which to retrieve the bean definition
//      * @return the bean definition
//      */
//     public static BeanDefinition getBeanDefinitionForTenant(final BeanDefinitionRegistry registry, final String baseBeanName,
//             final String tenantDomain)
//     {
//         ParameterCheck.mandatory("registry", registry);
//         ParameterCheck.mandatoryString("baseBeanName", baseBeanName);
//         ParameterCheck.mandatoryString("tenantDomain", tenantDomain);
// 
//         final String expectedBeanName = baseBeanName + TENANT_BEAN_NAME_PATTERN + tenantDomain;
//         final BeanDefinition beanDefinition = registry.getBeanDefinition(expectedBeanName);
//         return beanDefinition;
//     }
// 
//     /**
//      * Retrieves a specific bean for a specific tenant from the provided application context. This operation should only be used when each
//      * tenant domain is backed by its own implementation bean for a feature and calls need to be delegated according to the tenant domain.
//      *
//      * @param applicationContext
//      *            the application context from which to retrieve the bean
//      * @param baseBeanName
//      *            the base bean name
//      * @param tenantDomain
//      *            the tenant domain for which to retrieve the bean
//      * @param expectedType
//      *            the expected class or interface to which the bean must conform
//      * @return the bean
//      */
//     public static <T> T getBeanForTenant(final ApplicationContext applicationContext, final String baseBeanName, final String tenantDomain,
//             final Class<T> expectedType)
//     {
//         ParameterCheck.mandatory("applicationContext", applicationContext);
//         ParameterCheck.mandatoryString("baseBeanName", baseBeanName);
//         ParameterCheck.mandatoryString("tenantDomain", tenantDomain);
//         ParameterCheck.mandatory("expectedType", expectedType);
// 
//         final String expectedBeanName = baseBeanName + TENANT_BEAN_NAME_PATTERN + tenantDomain;
//         final T bean = applicationContext.getBean(expectedBeanName, expectedType);
//         return bean;
//     }
// }


// Path: repository/src/main/java/de/acosix/alfresco/mtsupport/repo/subsystems/TenantAwareSubsystemPlaceholderConfigurer.java
import java.util.Properties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionVisitor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.beans.factory.config.TypedStringValue;
import org.springframework.util.StringValueResolver;
import de.acosix.alfresco.mtsupport.repo.beans.TenantBeanUtils;

                    final TypedStringValue typedStringValue = (TypedStringValue) value;
                    final String stringValue = typedStringValue.getValue();
                    if (stringValue != null)
                    {
                        final String visitedString = this.resolveStringValue(stringValue);
                        if (!stringValue.equals(visitedString))
                        {
                            result = typedStringValue.hasTargetType()
                                    ? new TypedStringValue(visitedString, typedStringValue.getTargetType())
                                    : new TypedStringValue(visitedString);
                        }
                    }
                }
                else
                {
                    result = super.resolveValue(value);
                }

                return result;
            }
        };

        final String[] beanNames = beanFactoryToProcess.getBeanDefinitionNames();
        for (final String curName : beanNames)
        {
            // Check that we're not parsing our own bean definition,
            // to avoid failing on unresolvable placeholders in properties file locations.
            if (!(curName.equals(this.beanName) && beanFactoryToProcess.equals(this.beanFactory)))
            {
                final String tenantDomain;
                if (curName.contains(TenantBeanUtils.TENANT_BEAN_NAME_PATTERN))