// Path: props-common/src/main/java/base/props4j/impl/ElHolder.java
// public class ElHolder {
// 	
// 	private ValsHolder valsHolder;
// 	private ConcurrentHashMap<String, CacheData> cache;
// 
// 	public ElHolder(ValsHolder props) {
// 		this.valsHolder = props;
// 		this.cache = new ConcurrentHashMap<>();
// 	}
// 	
// 	public String getValAfterEl(String key){
// 		return getValAfterEl(key, null);
// 	}
// 	
// 	public String getValAfterEl(String key, String defVal){
// 		
// 		CacheData fromCache = cache.get(key);
// 		if(fromCache != null){
// 			if( ! fromCache.hasEl)
// 				return valsHolder.strVal(key, defVal);
// 			return fromCache.val;
// 		}
// 		
// 		String initVal = valsHolder.strVal(key, defVal);
// 		Pair<String, Boolean> result = processElIfNeed(initVal, valsHolder);
// 		boolean updatedByEl = result.second;
// 		String out = result.first;
// 		
// 		CacheData toCache = updatedByEl? new CacheData(out) : new CacheData();
// 		cache.put(key, toCache);
// 		
// 		return out;
// 	}
// 	
// 	public void clearCache(){
// 		cache.clear();
// 	}
// 	
// 	
// 	
// 	
// 	private static class CacheData {
// 		
// 		boolean hasEl;
// 		String val;
// 		 
// 		CacheData() {
// 			this.hasEl = false;
// 		}
// 		
// 		CacheData(String val) {
// 			this.val = val;
// 			this.hasEl = true;
// 		}
// 		
// 	}
// 
// }
// 
// Path: props-common/src/test/java/base/props4j/junit/AssertExt.java
// public class AssertExt extends Assert {
// 	
// 	public static void fail_TODO(){
// 		fail("TODO");
// 	}
// 	
// 	public static void fail_exception_expected(){
// 		fail_exception_expected(null);
// 	}
// 	
// 	public static void fail_exception_expected(String info){
// 		fail("Exception expected"+(info != null? ": "+info : ""));
// 	}
// 	
// 	public static void assertExceptionWithText(Throwable t, String... texts){
// 		assertTrue(t.toString(), containsAnyTextInMessage(t, texts));
// 	}
// 	
// 	public static void assertFileExists(String path){
// 		assertTrue("assertFileExists:"+path, new File(path).exists());
// 	}
// 	
// 	public static void assertFileNotExists(String path){
// 		assertTrue("assertFileNotExists:"+path, ! new File(path).exists());
// 	}
// 	
// 	public static void assertEquals(String expected, String actual){
// 		assertEquals((Object)expected, (Object)actual);
// 	}
// 	
// 	@SuppressWarnings("deprecation")
// 	public static void assertEquals(Object[] a, Object[] b){
// 		Assert.assertEquals(a, b);
// 	}
// 	
// 	public static void assertEquals(String expected, InputStream in){
// 		try {
// 			String actual = in == null? null : StreamUtil.streamToStr(in);
// 			assertEquals(expected, actual);
// 		}catch (Exception e) {
// 			throw ExceptionUtil.getRuntimeExceptionOrThrowError(e);
// 		}
// 	}
// 	
// 	public static void assertEquals(byte[] expected, byte[] actual){
// 		assertTrue("arrays are not equals", Arrays.equals(expected, actual));
// 	}
// 	
// 
// }


import base.props4j.impl.ElHolder;
import base.props4j.junit.AssertExt;
import java.util.HashMap;
import org.junit.Test;
package base.props4j;




public class ElHolderTest extends AssertExt {
	
	@Test
	public void test_cache(){
		
		HashMap<String, String> map = new HashMap<>();
		map.put("a", "a"); //no el
		map.put("b", "${c}"); //has el
		map.put("c", "${d}"); //no val for el - like "no el"
		
// Path: props-common/src/main/java/base/props4j/impl/ElHolder.java
// public class ElHolder {
// 	
// 	private ValsHolder valsHolder;
// 	private ConcurrentHashMap<String, CacheData> cache;
// 
// 	public ElHolder(ValsHolder props) {
// 		this.valsHolder = props;
// 		this.cache = new ConcurrentHashMap<>();
// 	}
// 	
// 	public String getValAfterEl(String key){
// 		return getValAfterEl(key, null);
// 	}
// 	
// 	public String getValAfterEl(String key, String defVal){
// 		
// 		CacheData fromCache = cache.get(key);
// 		if(fromCache != null){
// 			if( ! fromCache.hasEl)
// 				return valsHolder.strVal(key, defVal);
// 			return fromCache.val;
// 		}
// 		
// 		String initVal = valsHolder.strVal(key, defVal);
// 		Pair<String, Boolean> result = processElIfNeed(initVal, valsHolder);
// 		boolean updatedByEl = result.second;
// 		String out = result.first;
// 		
// 		CacheData toCache = updatedByEl? new CacheData(out) : new CacheData();
// 		cache.put(key, toCache);
// 		
// 		return out;
// 	}
// 	
// 	public void clearCache(){
// 		cache.clear();
// 	}
// 	
// 	
// 	
// 	
// 	private static class CacheData {
// 		
// 		boolean hasEl;
// 		String val;
// 		 
// 		CacheData() {
// 			this.hasEl = false;
// 		}
// 		
// 		CacheData(String val) {
// 			this.val = val;
// 			this.hasEl = true;
// 		}
// 		
// 	}
// 
// }
// 
// Path: props-common/src/test/java/base/props4j/junit/AssertExt.java
// public class AssertExt extends Assert {
// 	
// 	public static void fail_TODO(){
// 		fail("TODO");
// 	}
// 	
// 	public static void fail_exception_expected(){
// 		fail_exception_expected(null);
// 	}
// 	
// 	public static void fail_exception_expected(String info){
// 		fail("Exception expected"+(info != null? ": "+info : ""));
// 	}
// 	
// 	public static void assertExceptionWithText(Throwable t, String... texts){
// 		assertTrue(t.toString(), containsAnyTextInMessage(t, texts));
// 	}
// 	
// 	public static void assertFileExists(String path){
// 		assertTrue("assertFileExists:"+path, new File(path).exists());
// 	}
// 	
// 	public static void assertFileNotExists(String path){
// 		assertTrue("assertFileNotExists:"+path, ! new File(path).exists());
// 	}
// 	
// 	public static void assertEquals(String expected, String actual){
// 		assertEquals((Object)expected, (Object)actual);
// 	}
// 	
// 	@SuppressWarnings("deprecation")
// 	public static void assertEquals(Object[] a, Object[] b){
// 		Assert.assertEquals(a, b);
// 	}
// 	
// 	public static void assertEquals(String expected, InputStream in){
// 		try {
// 			String actual = in == null? null : StreamUtil.streamToStr(in);
// 			assertEquals(expected, actual);
// 		}catch (Exception e) {
// 			throw ExceptionUtil.getRuntimeExceptionOrThrowError(e);
// 		}
// 	}
// 	
// 	public static void assertEquals(byte[] expected, byte[] actual){
// 		assertTrue("arrays are not equals", Arrays.equals(expected, actual));
// 	}
// 	
// 
// }


// Path: props-common/src/test/java/base/props4j/ElHolderTest.java
import base.props4j.impl.ElHolder;
import base.props4j.junit.AssertExt;
import java.util.HashMap;
import org.junit.Test;

package base.props4j;




public class ElHolderTest extends AssertExt {
	
	@Test
	public void test_cache(){
		
		HashMap<String, String> map = new HashMap<>();
		map.put("a", "a"); //no el
		map.put("b", "${c}"); //has el
		map.put("c", "${d}"); //no val for el - like "no el"
		
		ElHolder holder = new ElHolder((key, def)->{