// Path: src/main/java/com/tngtech/propertyloader/impl/filters/EnvironmentResolvingFilter.java
// public class EnvironmentResolvingFilter extends ValueModifyingFilter {
// 
//     private static final Logger log = LoggerFactory.getLogger(EnvironmentResolvingFilter.class);
// 
//     private static final Pattern PATTERN = Pattern.compile("\\$ENV\\{(.*)\\}");
// 
//     @Override
//     protected String filterValue(String key, String value, Properties properties) {
//         Matcher matcher = PATTERN.matcher(value);
//         if (matcher.matches()) {
//             value = getenv(matcher.group(1));
//             if (value == null) {
//                 log.warn("There is no system property called '{}'.", matcher.group(1));
//             }
//         }
//         return value;
//     }
// 
//     protected String getenv(String key) {
//         return System.getenv(key);
//     }
// }
// 
// Path: src/main/java/com/tngtech/propertyloader/impl/filters/ThrowIfPropertyHasToBeDefined.java
// public class ThrowIfPropertyHasToBeDefined implements PropertyLoaderFilter {
// 
//     public static final String HAS_TO_BE_DEFINED = "<HAS_TO_BE_DEFINED>";
// 
//     @Override
//     public void filter(Properties properties) {
//         for (Map.Entry<Object, Object> entry : properties.entrySet()) {
//             String key = entry.getKey().toString();
//             String value = entry.getValue().toString();
//             if (HAS_TO_BE_DEFINED.equals(value)) {
//                 StringBuilder sb = new StringBuilder();
//                 sb.append("\n" + "Configuration incomplete: property ").append(key).append(" is still mapped to ").append(value);
//                 properties.remove(entry.getKey());
//                 try {
//                     filter(properties);
//                 } catch (ThrowIfPropertyHasToBeDefinedException e) {
//                     sb.append(e.getMessage());
//                 }
//                 throw new ThrowIfPropertyHasToBeDefinedException(sb.toString());
//             }
//         }
//     }
// 
// }
// 
// Path: src/main/java/com/tngtech/propertyloader/impl/filters/VariableResolvingFilter.java
// public class VariableResolvingFilter extends ValueModifyingFilter {
// 
//     private static final String VARIABLE_PREFIX = "${";
//     private static final String VARIABLE_SUFFIX = "}";
// 
//     @Override
//     protected String filterValue(String key, String value, Properties properties) {
//         if (!value.contains(VARIABLE_PREFIX)) {
//             return value;
//         }
// 
//         int startIndex = value.lastIndexOf(VARIABLE_PREFIX);
//         int endIndex = value.indexOf(VARIABLE_SUFFIX, startIndex + VARIABLE_PREFIX.length());
// 
//         String prefix = value.substring(0, startIndex);
//         String variableName = value.substring(startIndex + VARIABLE_PREFIX.length(), endIndex);
//         String suffix = value.substring(endIndex + VARIABLE_SUFFIX.length());
// 
//         String replacement = findReplacement(variableName, properties);
//         if (replacement == null) {
//             throw new VariableResolvingFilterException("Error during variable resolution: No value found for variable " + variableName);
//         }
//         String replacedValue = prefix + replacement + suffix;
// 
//         // In case this is a "${deeply${nested}}${variable}", look for something to resolve again
//         return filterValue(key, replacedValue, properties);
//     }
// 
//     private String findReplacement(String variableName, Properties properties) {
//         String result = properties.getProperty(variableName);
//         if (result != null) {
//             return result;
//         }
//         return System.getProperty(variableName);
//     }
// }
// 
// Path: src/main/java/com/tngtech/propertyloader/impl/filters/WarnOnSurroundingWhitespace.java
// public class WarnOnSurroundingWhitespace extends ValueModifyingFilter {
// 
//     private static final Logger log = LoggerFactory.getLogger(WarnOnSurroundingWhitespace.class);
// 
//     @Override
//     protected String filterValue(String key, String value, Properties properties) {
//         // don't show lines that end with "\n", that is ok and sometimes needed
//         if (!value.trim().equals(value) && !value.endsWith("\n")) {
//             log.warn("Key '{}' mapped to '{}', containing whitespace at the end. You probably do not want this.", key, value);
//         }
// 
//         return value;
//     }
// }


import com.tngtech.propertyloader.impl.filters.EnvironmentResolvingFilter;
import com.tngtech.propertyloader.impl.filters.ThrowIfPropertyHasToBeDefined;
import com.tngtech.propertyloader.impl.filters.VariableResolvingFilter;
import com.tngtech.propertyloader.impl.filters.WarnOnSurroundingWhitespace;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import java.net.MalformedURLException;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.when;
package com.tngtech.propertyloader.impl;




@RunWith(MockitoJUnitRunner.class)
public class DefaultPropertyFilterContainerTest {

    @InjectMocks
    private DefaultPropertyFilterContainer propertyFilter;

    @Mock
    private PropertyLoaderFactory propertyLoaderFactory;
    @Mock
    private VariableResolvingFilter variableResolvingFilter;
    @Mock
    private EnvironmentResolvingFilter environmentResolvingFilter;
    @Mock
    private WarnOnSurroundingWhitespace warnOnSurroundingWhitespace;
    @Mock
// Path: src/main/java/com/tngtech/propertyloader/impl/filters/EnvironmentResolvingFilter.java
// public class EnvironmentResolvingFilter extends ValueModifyingFilter {
// 
//     private static final Logger log = LoggerFactory.getLogger(EnvironmentResolvingFilter.class);
// 
//     private static final Pattern PATTERN = Pattern.compile("\\$ENV\\{(.*)\\}");
// 
//     @Override
//     protected String filterValue(String key, String value, Properties properties) {
//         Matcher matcher = PATTERN.matcher(value);
//         if (matcher.matches()) {
//             value = getenv(matcher.group(1));
//             if (value == null) {
//                 log.warn("There is no system property called '{}'.", matcher.group(1));
//             }
//         }
//         return value;
//     }
// 
//     protected String getenv(String key) {
//         return System.getenv(key);
//     }
// }
// 
// Path: src/main/java/com/tngtech/propertyloader/impl/filters/ThrowIfPropertyHasToBeDefined.java
// public class ThrowIfPropertyHasToBeDefined implements PropertyLoaderFilter {
// 
//     public static final String HAS_TO_BE_DEFINED = "<HAS_TO_BE_DEFINED>";
// 
//     @Override
//     public void filter(Properties properties) {
//         for (Map.Entry<Object, Object> entry : properties.entrySet()) {
//             String key = entry.getKey().toString();
//             String value = entry.getValue().toString();
//             if (HAS_TO_BE_DEFINED.equals(value)) {
//                 StringBuilder sb = new StringBuilder();
//                 sb.append("\n" + "Configuration incomplete: property ").append(key).append(" is still mapped to ").append(value);
//                 properties.remove(entry.getKey());
//                 try {
//                     filter(properties);
//                 } catch (ThrowIfPropertyHasToBeDefinedException e) {
//                     sb.append(e.getMessage());
//                 }
//                 throw new ThrowIfPropertyHasToBeDefinedException(sb.toString());
//             }
//         }
//     }
// 
// }
// 
// Path: src/main/java/com/tngtech/propertyloader/impl/filters/VariableResolvingFilter.java
// public class VariableResolvingFilter extends ValueModifyingFilter {
// 
//     private static final String VARIABLE_PREFIX = "${";
//     private static final String VARIABLE_SUFFIX = "}";
// 
//     @Override
//     protected String filterValue(String key, String value, Properties properties) {
//         if (!value.contains(VARIABLE_PREFIX)) {
//             return value;
//         }
// 
//         int startIndex = value.lastIndexOf(VARIABLE_PREFIX);
//         int endIndex = value.indexOf(VARIABLE_SUFFIX, startIndex + VARIABLE_PREFIX.length());
// 
//         String prefix = value.substring(0, startIndex);
//         String variableName = value.substring(startIndex + VARIABLE_PREFIX.length(), endIndex);
//         String suffix = value.substring(endIndex + VARIABLE_SUFFIX.length());
// 
//         String replacement = findReplacement(variableName, properties);
//         if (replacement == null) {
//             throw new VariableResolvingFilterException("Error during variable resolution: No value found for variable " + variableName);
//         }
//         String replacedValue = prefix + replacement + suffix;
// 
//         // In case this is a "${deeply${nested}}${variable}", look for something to resolve again
//         return filterValue(key, replacedValue, properties);
//     }
// 
//     private String findReplacement(String variableName, Properties properties) {
//         String result = properties.getProperty(variableName);
//         if (result != null) {
//             return result;
//         }
//         return System.getProperty(variableName);
//     }
// }
// 
// Path: src/main/java/com/tngtech/propertyloader/impl/filters/WarnOnSurroundingWhitespace.java
// public class WarnOnSurroundingWhitespace extends ValueModifyingFilter {
// 
//     private static final Logger log = LoggerFactory.getLogger(WarnOnSurroundingWhitespace.class);
// 
//     @Override
//     protected String filterValue(String key, String value, Properties properties) {
//         // don't show lines that end with "\n", that is ok and sometimes needed
//         if (!value.trim().equals(value) && !value.endsWith("\n")) {
//             log.warn("Key '{}' mapped to '{}', containing whitespace at the end. You probably do not want this.", key, value);
//         }
// 
//         return value;
//     }
// }


// Path: src/test/java/com/tngtech/propertyloader/impl/DefaultPropertyFilterContainerTest.java
import com.tngtech.propertyloader.impl.filters.EnvironmentResolvingFilter;
import com.tngtech.propertyloader.impl.filters.ThrowIfPropertyHasToBeDefined;
import com.tngtech.propertyloader.impl.filters.VariableResolvingFilter;
import com.tngtech.propertyloader.impl.filters.WarnOnSurroundingWhitespace;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import java.net.MalformedURLException;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.when;

package com.tngtech.propertyloader.impl;




@RunWith(MockitoJUnitRunner.class)
public class DefaultPropertyFilterContainerTest {

    @InjectMocks
    private DefaultPropertyFilterContainer propertyFilter;

    @Mock
    private PropertyLoaderFactory propertyLoaderFactory;
    @Mock
    private VariableResolvingFilter variableResolvingFilter;
    @Mock
    private EnvironmentResolvingFilter environmentResolvingFilter;
    @Mock
    private WarnOnSurroundingWhitespace warnOnSurroundingWhitespace;
    @Mock
    private ThrowIfPropertyHasToBeDefined throwIfPropertyHasToBeDefined;