EXTSCRIPT-154: Code Rewrite/Refactoring, annotations now work

git-svn-id: https://svn.apache.org/repos/asf/myfaces/extensions/scripting/trunk@1299999 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/core/context/Configuration.java b/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/core/context/Configuration.java
index 187d07c..5eeed5f 100644
--- a/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/core/context/Configuration.java
+++ b/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/core/context/Configuration.java
@@ -29,6 +29,8 @@
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentSkipListSet;
 import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicLong;
 
 import static rewrite.org.apache.myfaces.extensions.scripting.core.api.ScriptingConst.*;
 
@@ -60,6 +62,7 @@
 
     String _initialCompile;
 
+
     /**
      * the target compile path
      */
@@ -247,3 +250,4 @@
 
 
 }
+
diff --git a/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/core/context/WeavingContext.java b/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/core/context/WeavingContext.java
index d0fb935..ac8dfcf 100644
--- a/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/core/context/WeavingContext.java
+++ b/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/core/context/WeavingContext.java
@@ -20,7 +20,10 @@
 package rewrite.org.apache.myfaces.extensions.scripting.core.context;
 
 import rewrite.org.apache.myfaces.extensions.scripting.core.api.Decorated;
+import rewrite.org.apache.myfaces.extensions.scripting.core.common.util.ClassUtils;
+import rewrite.org.apache.myfaces.extensions.scripting.core.common.util.ReflectUtil;
 import rewrite.org.apache.myfaces.extensions.scripting.core.engine.FactoryEngines;
+import rewrite.org.apache.myfaces.extensions.scripting.core.engine.api.ClassScanner;
 import rewrite.org.apache.myfaces.extensions.scripting.core.engine.api.ScriptingEngine;
 import rewrite.org.apache.myfaces.extensions.scripting.core.loader.ThrowAwayClassloader;
 import rewrite.org.apache.myfaces.extensions.scripting.core.monitor.ClassResource;
@@ -36,6 +39,7 @@
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.logging.Logger;
 
@@ -58,13 +62,33 @@
 
     ImplementationSPI _implementation = null;
     GlobalReloadingStrategy _reloadingStrategy = new GlobalReloadingStrategy();
-
+    ClassScanner _annotationScanner = null;
     Logger log = Logger.getLogger(this.getClass().getName());
     boolean _scriptingEnabled = true;
 
+    /*holder for various operations within our lifecycle*/
+    ConcurrentHashMap<String, Long> lifecycleRegistry = new ConcurrentHashMap<String, Long>();
+
     public void initEngines() throws IOException
     {
         FactoryEngines.getInstance().init();
+        initScanner();
+    }
+
+    public void initScanner()
+    {
+        try
+        {
+            Class scanner = ClassUtils.getContextClassLoader().loadClass("rewrite.org.apache.myfaces.extensions.scripting.jsf.annotation.GenericAnnotationScanner");
+            this._annotationScanner = (ClassScanner) ReflectUtil.instantiate(scanner);
+
+        }
+        catch (ClassNotFoundException e)
+        {
+            //we do nothing here
+            //generic annotation scanner can be missing in jsf 1.2 environments
+            //_logger.log(Level.FINER, "", e);
+        }
     }
 
     public Collection<ScriptingEngine> getEngines()
@@ -110,15 +134,16 @@
     {
         for (ScriptingEngine engine : getEngines())
         {
-            if(!engine.getWatchedResources().containsKey(key)) continue;
+            if (!engine.getWatchedResources().containsKey(key)) continue;
             return engine.getWatchedResources().get(key);
         }
         return null;
     }
-    
-    public boolean isTainted(String key) {
+
+    public boolean isTainted(String key)
+    {
         ClassResource res = getWatchedResource(key);
-        if(res == null) return false;
+        if (res == null) return false;
         return res.isTainted();
     }
 
@@ -152,10 +177,17 @@
     {
         for (ScriptingEngine engine : getEngines())
         {
-            //log.info("[EXT-SCRIPTING] scanning " + engine.getEngineType() + " files");
             engine.scanForAddedDeleted();
-            //log.info("[EXT-SCRIPTING] scanning " + engine.getEngineType() + " files done");
         }
+        //the scanner scans only the tainted classes
+        //hence this should work whatever happens
+
+    }
+
+    public void annotationScan()
+    {
+        if (_annotationScanner != null)
+            _annotationScanner.scanPaths();
     }
 
     public boolean compile()
@@ -306,6 +338,42 @@
     }
 
     //----------------------------------------------------------------------
+    //lifecycle related tasks
+    public boolean isPostInit()
+    {
+        return (lifecycleRegistry.get("LIFECYCLE_POST_INIT") != null);
+    }
+
+    public void markPostInit()
+    {
+        lifecycleRegistry.put("LIFECYCLE_POST_INIT", System.currentTimeMillis());
+    }
+
+    public void markLastTaint()
+    {
+        lifecycleRegistry.put("LIFECYCLE_LAST_TAINTED", System.currentTimeMillis());
+    }
+
+    public long getLastTaint()
+    {
+        Long lastTainted = lifecycleRegistry.get("LIFECYCLE_LAST_TAINTED");
+        lastTainted = (lastTainted != null) ? lastTainted : -1L;
+        return lastTainted;
+    }
+
+    public void markLastAnnotationScan()
+    {
+        lifecycleRegistry.put("LIFECYCLE_LAST_ANN_SCAN", System.currentTimeMillis());
+    }
+
+    public long getLastAnnotationScan()
+    {
+        Long lastTainted = lifecycleRegistry.get("LIFECYCLE_LAST_ANN_SCAN");
+        lastTainted = (lastTainted != null) ? lastTainted : -1L;
+        return lastTainted;
+    }
+
+    //----------------------------------------------------------------------
     /*public ClassDependencies getDependencyMap()
     {
         return _dependencyMap;
@@ -342,4 +410,5 @@
     {
         _scriptingEnabled = scriptingEnabled;
     }
+
 }
diff --git a/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/core/engine/BaseEngine.java b/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/core/engine/BaseEngine.java
index 8a87f5c..c4ab95d 100644
--- a/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/core/engine/BaseEngine.java
+++ b/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/core/engine/BaseEngine.java
@@ -19,8 +19,8 @@
 package rewrite.org.apache.myfaces.extensions.scripting.core.engine;
 
 import org.apache.commons.io.FilenameUtils;
-import org.apache.myfaces.extensions.scripting.core.util.FileUtils;
 import rewrite.org.apache.myfaces.extensions.scripting.core.common.util.ClassUtils;
+import rewrite.org.apache.myfaces.extensions.scripting.core.common.util.FileUtils;
 import rewrite.org.apache.myfaces.extensions.scripting.core.engine.dependencyScan.api.DependencyRegistry;
 import rewrite.org.apache.myfaces.extensions.scripting.core.engine.dependencyScan.core.ClassDependencies;
 import rewrite.org.apache.myfaces.extensions.scripting.core.engine.dependencyScan.registry.DependencyRegistryImpl;
@@ -49,7 +49,13 @@
     DependencyRegistry _dependencyRegistry = new DependencyRegistryImpl(getEngineType(), _dependencyMap);
 
     Logger log = Logger.getLogger(this.getClass().getName());
-    
+
+
+    protected BaseEngine()
+    {
+
+    }
+
     public Map<String, ClassResource> getWatchedResources()
     {
         return _watchedResources;
@@ -67,7 +73,8 @@
     /**
      * @return a collection of possible dynamic classes
      */
-    public Collection<String> getPossibleDynamicClasses() {
+    public Collection<String> getPossibleDynamicClasses()
+    {
         return _watchedResources.keySet();
     }
 
@@ -75,66 +82,76 @@
      * runs a full scan of files to get a list of files which need to be processed
      * for the future
      */
-    public void scanForAddedDeleted() {
+    public void scanForAddedDeleted()
+    {
         Set<String> processedClasses = new HashSet<String>();
         processedClasses.addAll(_watchedResources.keySet());
-        
-        for(String sourcePath: getSourcePaths()) {
-           Collection<File> sourceFiles = FileUtils.fetchSourceFiles(new File(sourcePath), "*."+ getFileEnding());
-           
-            for(File sourceFile: sourceFiles) {
-               ClassResource classToProcess = new ClassResource();
+
+        for (String sourcePath : getSourcePaths())
+        {
+            Collection<File> sourceFiles = FileUtils.fetchSourceFiles(new File(sourcePath), "*." + getFileEnding());
+
+            for (File sourceFile : sourceFiles)
+            {
+                ClassResource classToProcess = new ClassResource();
                 classToProcess.setFile(sourceFile);
                 classToProcess.setLastLoaded(-1);
                 classToProcess.setScriptingEngine(getEngineType());
-                if(!_watchedResources.containsKey(classToProcess.getIdentifier())) {
+                if (!_watchedResources.containsKey(classToProcess.getIdentifier()))
+                {
                     _watchedResources.put(classToProcess.getIdentifier(), classToProcess);
-               } else {
-                   processedClasses.remove(classToProcess.getIdentifier());
-                   
-                   classToProcess = _watchedResources.get(classToProcess.getIdentifier());
-               }
-               if(classToProcess.needsRecompile()) {
-                   //TODO add entry for logging component here
-                   log.info("[EXT-SCRIPTING] tainting "+classToProcess.getIdentifier());
-                   classToProcess.setTainted(true);
-                   classToProcess.setChangedForCompile(true);
-               }
-           }
+                } else
+                {
+                    processedClasses.remove(classToProcess.getIdentifier());
+
+                    classToProcess = _watchedResources.get(classToProcess.getIdentifier());
+                }
+                if (classToProcess.needsRecompile())
+                {
+                    //TODO add entry for logging component here
+                    log.info("[EXT-SCRIPTING] tainting " + classToProcess.getIdentifier());
+                    classToProcess.setTainted(true);
+                    classToProcess.setChangedForCompile(true);
+                }
+            }
         }
-        for(String deleted:processedClasses) {
+        for (String deleted : processedClasses)
+        {
             _watchedResources.remove(deleted);
         }
 
-
     }
 
     /**
      * checks whether we have resources which are in need of a recompile
+     *
      * @return
      */
-    public boolean needsRecompile() {
+    public boolean needsRecompile()
+    {
         //TODO buffer this from scan
-        for(Map.Entry<String, ClassResource> resource: _watchedResources.entrySet()) {
-            if(resource.getValue().needsRecompile()) return true;
+        for (Map.Entry<String, ClassResource> resource : _watchedResources.entrySet())
+        {
+            if (resource.getValue().needsRecompile()) return true;
         }
         return false;
     }
 
     /**
      * checks whether we have resources which are tainted
+     *
      * @return
      */
-    public boolean isTainted() {
+    public boolean isTainted()
+    {
         //TODO buffer this from scan
-        for(Map.Entry<String, ClassResource> resource: _watchedResources.entrySet()) {
-            if(resource.getValue().isTainted()) return true;
+        for (Map.Entry<String, ClassResource> resource : _watchedResources.entrySet())
+        {
+            if (resource.getValue().isTainted()) return true;
         }
         return false;
     }
 
-
-
     public DependencyRegistry getDependencyRegistry()
     {
         return _dependencyRegistry;
@@ -155,8 +172,6 @@
         _dependencyMap = dependencyMap;
     }
 
-
-    
     /**
      * marks all the dependencies of the tainted objects
      * also as tainted to allow proper refreshing.
@@ -171,7 +186,7 @@
             ClassResource resource = entry.getValue();
             if (!resource.isChangedForCompile()) continue;
             resource.setChangedForCompile(false);
-            log.info("[EXT-SCRIPTING] tainting dependency "+resource.getIdentifier());
+            log.info("[EXT-SCRIPTING] tainting dependency " + resource.getIdentifier());
             resource.setTainted(true);
             //classname
             String identifier = resource.getIdentifier();
@@ -186,21 +201,22 @@
     private void markDependencies(Set<String> _processedClasses, String identifier)
     {
         Set<String> referringClasses = _dependencyMap.getReferringClasses(identifier);
-        if(referringClasses == null) return;
+        if (referringClasses == null) return;
         for (String referringClass : referringClasses)
         {
             if (_processedClasses.contains(referringClass)) continue;
             ClassResource toTaint = _watchedResources.get(referringClass);
-            if(toTaint == null) continue;
+            if (toTaint == null) continue;
             //TODO add entry for logging component here
-            if(toTaint.isTainted()) {
-                log.info("[EXT-SCRIPTING] dependency already tainted:"+toTaint.getIdentifier());
+            if (toTaint.isTainted())
+            {
+                log.info("[EXT-SCRIPTING] dependency already tainted:" + toTaint.getIdentifier());
                 _processedClasses.add(toTaint.getIdentifier());
                 continue;
             }
             toTaint.setTainted(true);
             toTaint.setChangedForCompile(false);
-            log.info("[EXT-SCRIPTING] tainting dependency "+toTaint.getIdentifier());
+            log.info("[EXT-SCRIPTING] tainting dependency " + toTaint.getIdentifier());
             _processedClasses.add(toTaint.getIdentifier());
             markDependencies(_processedClasses, toTaint.getIdentifier());
         }
@@ -208,18 +224,18 @@
     }
 
     protected void initPaths(ServletContext context, String initParam, String defaultValue)
+    {
+        String pathSeparatedList = context.getInitParameter(initParam);
+        pathSeparatedList = (pathSeparatedList != null) ? pathSeparatedList : defaultValue;
+        if (pathSeparatedList.equals(defaultValue))
         {
-            String pathSeparatedList = context.getInitParameter(initParam);
-            pathSeparatedList = (pathSeparatedList != null) ? pathSeparatedList : defaultValue;
-            if (pathSeparatedList.equals(defaultValue))
-            {
-                URL resource = ClassUtils.getContextClassLoader().getResource("./");
-                pathSeparatedList = FilenameUtils.normalize(resource.getPath() + "../.." + defaultValue);
-            }
-            String[] paths = pathSeparatedList.split(",");
-            for (String path : paths)
-            {
-                getSourcePaths().add(path);
-            }
+            URL resource = ClassUtils.getContextClassLoader().getResource("./");
+            pathSeparatedList = FilenameUtils.normalize(resource.getPath() + "../.." + defaultValue);
         }
+        String[] paths = pathSeparatedList.split(",");
+        for (String path : paths)
+        {
+            getSourcePaths().add(path);
+        }
+    }
 }
diff --git a/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/core/engine/BaseScanner.java b/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/core/engine/BaseScanner.java
index 3bd2fff..ca8bb84 100644
--- a/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/core/engine/BaseScanner.java
+++ b/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/core/engine/BaseScanner.java
@@ -45,43 +45,55 @@
 
 public abstract class BaseScanner
 {
-    List<String> _scanPaths = new LinkedList<String>();DependencyScanner _depencyScanner = new StandardDependencyScanner();Logger _log = Logger.getLogger(JavaDependencyScanner.class.getName());
+    List<String> _scanPaths = new LinkedList<String>();
+    DependencyScanner _depencyScanner = new StandardDependencyScanner();
+    Logger _log = Logger.getLogger(JavaDependencyScanner.class.getName());
 
     public abstract int getEngineType();
 
     public abstract String getFileEnding();
 
-    public synchronized void scanPaths() {
+    public synchronized void scanPaths()
+    {
         //only one dependency check per refresh makes sense in our case
-       /* if (WeavingContext.getRefreshContext().isDependencyScanned(getEngineType())) {
+        /* if (WeavingContext.getRefreshContext().isDependencyScanned(getEngineType())) {
             return;
         } else {
             WeavingContext.getRefreshContext().setDependencyScanned(getEngineType(), true);
         }*/
         ScriptingEngine engine = WeavingContext.getInstance().getEngine(ScriptingConst.ENGINE_TYPE_JSF_JAVA);
 
-        if (_log.isLoggable(Level.INFO)) {
+        if (_log.isLoggable(Level.INFO))
+        {
             _log.info("[EXT-SCRITPING] starting class dependency scan");
         }
         long start = System.currentTimeMillis();
         final Set<String> possibleDynamicClasses = new HashSet<String>(engine.getPossibleDynamicClasses());
 
         final ClassLoader loader = getClassLoader();
-        for (String dynamicClass : possibleDynamicClasses) {
+        for (String dynamicClass : possibleDynamicClasses)
+        {
             runScan(possibleDynamicClasses, loader, dynamicClass);
         }
 
         long end = System.currentTimeMillis();
-        if (_log.isLoggable(Level.FINE)) {
+        if (_log.isLoggable(Level.FINE))
+        {
             _log.log(Level.FINE, "[EXT-SCRITPING] class dependency scan finished, duration: {0} ms", Long.toString(end - start));
         }
 
     }
 
-    private void runScan(final Set<String> possibleDynamicClasses, final ClassLoader loader, String dynamicClass) {
+    public void scanClass(Class clazz)
+    {
+        //TODO do nothing here
+    }
+
+    private void runScan(final Set<String> possibleDynamicClasses, final ClassLoader loader, String dynamicClass)
+    {
         //TODO implement the dep registry
         ExternalFilterDependencyRegistry scanRegistry = (ExternalFilterDependencyRegistry) WeavingContext.getInstance()
-        .getEngine(getEngineType()).getDependencyRegistry();
+                .getEngine(getEngineType()).getDependencyRegistry();
 
         scanRegistry.clearFilters();
         //We have to dynamically readjust the filters
@@ -90,8 +102,10 @@
                 WeavingContext.getInstance().getEngine(getEngineType()).getDependencyRegistry());
     }
 
-    protected ClassLoader getClassLoader() {
-        try {
+    protected ClassLoader getClassLoader()
+    {
+        try
+        {
             return AccessController.doPrivileged(new PrivilegedExceptionAction<ScannerClassloader>()
             {
                 public ScannerClassloader run()
@@ -100,13 +114,16 @@
                             getFileEnding(), WeavingContext.getInstance().getConfiguration().getCompileTarget());
                 }
             });
-        } catch (PrivilegedActionException e) {
-            _log.log(Level.SEVERE,"", e);
+        }
+        catch (PrivilegedActionException e)
+        {
+            _log.log(Level.SEVERE, "", e);
         }
         return null;
     }
 
-    public void addScanPath(String scanPath) {
+    public void addScanPath(String scanPath)
+    {
         _scanPaths.add(scanPath);
     }
 }
diff --git a/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/core/engine/JavaDependencyScanner.java b/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/core/engine/JavaDependencyScanner.java
index 74c424d..c61a8ad 100644
--- a/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/core/engine/JavaDependencyScanner.java
+++ b/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/core/engine/JavaDependencyScanner.java
@@ -40,4 +40,5 @@
         return ScriptingConst.JAVA_FILE_ENDING;
     }
 
+
 }
diff --git a/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/core/engine/api/ClassScanner.java b/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/core/engine/api/ClassScanner.java
index e39c9b4..68963c1 100644
--- a/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/core/engine/api/ClassScanner.java
+++ b/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/core/engine/api/ClassScanner.java
@@ -34,6 +34,7 @@
 public interface ClassScanner {
 
     public void scanPaths();
+    public void scanClass(Class clazz);
 
     public void addScanPath(String scanPath);
 
diff --git a/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/core/monitor/ClassResource.java b/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/core/monitor/ClassResource.java
index 6bacb17..0c5055f 100644
--- a/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/core/monitor/ClassResource.java
+++ b/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/core/monitor/ClassResource.java
@@ -149,6 +149,7 @@
         //if (isTainted()) return;
         if (value && !tainted)
         {
+            WeavingContext.getInstance().markLastTaint();
             //TODO add logging event here
             logger.info("[EXT-SCRIPTING] tainting " + getSourceFile());
         }
diff --git a/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/core/monitor/ResourceMonitor.java b/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/core/monitor/ResourceMonitor.java
index 5470026..1fef03f 100644
--- a/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/core/monitor/ResourceMonitor.java
+++ b/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/core/monitor/ResourceMonitor.java
@@ -25,6 +25,7 @@
 import java.lang.ref.WeakReference;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
@@ -48,6 +49,7 @@
 
     static ResourceMonitor _instance = null;
 
+
     //Map<String, ClassResource> _classMap = new ConcurrentHashMap<String, ClassResource>(8, 0.75f, 1);
     //ClassDependencies _dependencyMap = new ClassDependencies();
 
@@ -123,6 +125,7 @@
         {
             _log.info("[EXT-SCRIPTING] Dynamic reloading watch daemon is shutting down");
         }
+
     }
 
     public void initialMonitoring()
@@ -136,22 +139,27 @@
             context.scanDependencies();
             //we next retaint all classes according to our dependency graph
             context.markTaintedDependends();
+
         }
     }
 
     public void performMonitoringTask()
     {
-        WeavingContext context = WeavingContext.getInstance();
-        context.initialFullScan();
+        synchronized(WeavingContext.getInstance().recompileLock) {
+            WeavingContext context = WeavingContext.getInstance();
+            context.initialFullScan();
 
-        //we compile wherever needed, taints are now in place due to our scan already being performed
-        if (context.compile())
-        {
-            //we now have to perform a full dependency scan to bring our dependency map to the latest state
-            context.scanDependencies();
-            //we next retaint all classes according to our dependency graph
-            context.markTaintedDependends();
+            //we compile wherever needed, taints are now in place due to our scan already being performed
+            if (context.compile())
+            {
+                //we now have to perform a full dependency scan to bring our dependency map to the latest state
+                context.scanDependencies();
+                //we next retaint all classes according to our dependency graph
+                context.markTaintedDependends();
+            }
         }
+        //context.annotationScan();
+
     }
 
     private void sleep()
@@ -171,5 +179,7 @@
     {
         this._running = running;
     }
+
+
 }
 
diff --git a/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/jsf/annotation/GenericAnnotationScanner.java b/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/jsf/annotation/GenericAnnotationScanner.java
index 1d6472e..ad13069 100644
--- a/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/jsf/annotation/GenericAnnotationScanner.java
+++ b/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/jsf/annotation/GenericAnnotationScanner.java
@@ -110,6 +110,9 @@
             //to get the runtime config
             return;
         }
+        if(!_weaver.isPostInit() || _weaver.getLastAnnotationScan() >= _weaver.getLastTaint()) return;
+        _weaver.markLastAnnotationScan();
+
 
         for (String className : _weaver.loadPossibleDynamicClasses()) {
             try {
diff --git a/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/jsf/startup/AnnotationScanPhaseListener.java b/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/jsf/startup/AnnotationScanPhaseListener.java
new file mode 100644
index 0000000..1f1f9f6
--- /dev/null
+++ b/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/jsf/startup/AnnotationScanPhaseListener.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 rewrite.org.apache.myfaces.extensions.scripting.jsf.startup;
+
+import rewrite.org.apache.myfaces.extensions.scripting.core.context.WeavingContext;
+
+import javax.faces.context.FacesContext;
+import javax.faces.event.PhaseEvent;
+import javax.faces.event.PhaseId;
+import javax.faces.event.PhaseListener;
+import java.util.Map;
+
+/**
+ * @author Werner Punz (latest modification by $Author$)
+ * @version $Revision$ $Date$
+ *
+ * This phase listener is needed because the annotation scanner
+ * relies on the facesContext to be present, we cannot do without it
+ */
+public class AnnotationScanPhaseListener implements PhaseListener
+{
+
+    @Override
+    public void afterPhase(PhaseEvent event)
+    {
+        //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    @Override
+    public void beforePhase(PhaseEvent event)
+    {
+        FacesContext context = event.getFacesContext();
+        Map<Object, Object> params = context.getAttributes();
+        if(params.containsKey("ANN_PROCESSED")) return;
+        else params.put("ANN_PROCESSED", Boolean.TRUE);
+        WeavingContext.getInstance().annotationScan();
+    }
+
+    @Override
+    public PhaseId getPhaseId()
+    {
+        return PhaseId.ANY_PHASE;  //To change body of implemented methods use File | Settings | File Templates.
+    }
+}
diff --git a/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/jsf/startup/StartupServletContextPluginChainLoader.java b/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/jsf/startup/StartupServletContextPluginChainLoader.java
index e62ceb8..b465f1e 100644
--- a/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/jsf/startup/StartupServletContextPluginChainLoader.java
+++ b/extscript-core-root/extscript-core/src/main/java/rewrite/org/apache/myfaces/extensions/scripting/jsf/startup/StartupServletContextPluginChainLoader.java
@@ -27,6 +27,7 @@
 import javax.servlet.ServletContext;
 import javax.servlet.ServletContextEvent;
 import java.io.IOException;
+import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.logging.Logger;
 
 /**
@@ -77,11 +78,7 @@
     public void postInit(ServletContextEvent evt)
     {
         //tell the system that the startup phase is done
-        /*  WeavingContext.getWeaver().fullClassScan();
-        evt.getServletContext().setAttribute(ScriptingConst.CTX_ATTR_STARTUP, new AtomicBoolean(Boolean.FALSE));
-
-        WeavingContext.getExtensionEventRegistry().sendEvent(new SystemInitializedEvent());
-        */
+        WeavingContext.getInstance().markPostInit();
     }
 
     public void preDestroy(ServletContextEvent evt)