/*******************************************************************************
 * This file is part of TERMINAL RECALL
 * Copyright (c) 2015 Chuck Ritola
 * Part of the jTRFP.org project
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Public License v3.0
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/gpl.html
 * 
 * Contributors:
 *     chuck - initial API and implementation
 ******************************************************************************/
package org.jtrfp.trcl.ext;

import org.jtrfp.trcl.coll.CachedAdapter;

public class ExtensionSupport<PARENT> {
    private final PARENT parent;
    
    private final CachedAdapter<Class<? extends Extension<?>>,Extension<?>> extensionFactory = 
	    new CachedAdapter<Class<? extends Extension<?>>,Extension<?>>(){
	@Override
	protected Extension<?> _adapt(
		Class<? extends Extension<?>> value)
			throws UnsupportedOperationException {
	    try{Extension<PARENT> result = (Extension<PARENT>)value.newInstance();
	    final Class eClass = result.getExtendedClass();
	    final Class pClass = parent.getClass();
	    if(!eClass.equals(pClass))
		throw new UnsupportedOperationException(
			"Class mismatch. Extension: "+result.getExtendedClass().getName()+
			" Expected: "+pClass.getName());
	    System.out.println("Initializing Extension: "+result.getHumanReadableName());
	    result.init(parent);
	    return result;
	    }
	    catch(Exception e){throw new UnsupportedOperationException(e);}
	}//end _adapt()

	@Override
	protected Class<? extends Extension<?>> _reAdapt(
		Extension<?> value)
			throws UnsupportedOperationException {
	    throw new UnsupportedOperationException();
	}//end _reAdapt
    };
		
 //// C O N S T R U C T O R ////
 public ExtensionSupport(PARENT parent){
     this.parent=parent;
 }
 
 public<CLASS extends Extension<?>> Extension<?> getExtension(Class<CLASS> extensionClass){
     return extensionFactory.adapt(extensionClass);
 }
 
 public void loadBuiltInExtensions(){
     for(Class<? extends Extension> eClass:Extensions.builtInExtensions){
	 try{if(parent.getClass().isAssignableFrom(((Extension)(eClass.newInstance())).getExtendedClass()) || eClass.equals(parent.getClass()))
	     ((Extension<PARENT>)getExtension(eClass)).apply(parent);}catch(Exception e){e.printStackTrace();}
     }
 }
}//end ExtensionSupport

@@ -596,16 +596,171 @@
 l.ext;%0A%0A
+import java.util.HashSet;%0A%0Aimport org.apache.commons.collections4.map.AbstractReferenceMap.ReferenceStrength;%0Aimport org.jtrfp.trcl.coll.BidiReferenceMap;%0A
 import o
@@ -867,16 +867,89 @@
 parent;%0A
+    private final HashSet%3CExtension%3E applied = new HashSet%3CExtension%3E();%0A
     %0A   
@@ -1108,16 +1108,163 @@
 ion%3C?%3E%3E(
+%0A%09     new BidiReferenceMap%3CClass%3C? extends Extension%3C?%3E%3E,Extension%3C?%3E%3E%0A              (ReferenceStrength.HARD,ReferenceStrength.HARD, 64,.75f,true)
 )%7B%0A%09@Ove
@@ -2314,19 +2314,20 @@
 sion%3C?%3E 
-get
+peek
 Extensio
@@ -2411,24 +2411,287 @@
 lass);%0A %7D%0A %0A
+ public%3CCLASS extends Extension%3C?%3E%3E Extension%3C?%3E getExtension(Class%3CCLASS%3E extensionClass)%7B%0A     final Extension result = extensionFactory.adapt(extensionClass);%0A     if(applied.add(result))%0A%09 result.apply(parent);%0A     return result;%0A %7D//end getExtension(...)%0A %0A
  public void
@@ -2937,28 +2937,8 @@
     
-((Extension%3CPARENT%3E)
 getE
@@ -2957,23 +2957,8 @@
 ass)
-).apply(parent)
 ;%7Dca

Add peekExtension to ExtensionSupport and harden cache.