// Path: src/aeminium/runtime/Body.java
// public interface Body {
// 	/**
// 	 * This method contains the code of the body, that is executed by the task. 
// 	 * 
// 	 * @param current Reference to the associated task object.
// 	 */
//     public void execute(final Runtime rt, final Task current) throws Exception;
// }
// 
// Path: src/aeminium/runtime/Runtime.java
// public interface Runtime {
//     /* Global constants for default values */
//     public final static Collection<Task> NO_DEPS = new ArrayList<Task>() {
// 		private static final long serialVersionUID = 1852797887380877437L;
// 
// 		@Override 
// 		public String toString() {
// 			return "NO_DEPS"; 
// 		}
// 	};
//     public final static short NO_HINTS = Hints.NO_HINTS;
//     public final static Task NO_PARENT = new Task() {
// 		@Override
// 		public void setResult(Object value) {
// 			throw new Error("Cannot set result on NO_PARENT");
// 		}
// 
// 		@Override
// 		public Object getResult() {
// 			throw new Error("Cannot get result from NO_PARENT");
// 		}
// 		
// 		@Override
// 		public String toString() {
// 			return "NO_PARENT";
// 		}
// 	};
// 	
//     /* Initializes runtime. Should be called upon program start. */
//     public void init() ;
//     /* 
//      * Waits until all tasks are executed and frees
//      * all allocated resources. 
//      * Should be called at the end of the program. 
//      */
//     public void shutdown();
//     /* Waits until all tasks have been processed */
//     public void waitToEmpty();
//     /* 
//      * Submits a task for execution, providing the parent task as well
//      * as its dependencies.
//      *  */
//     public void schedule(Task task, Task parent, Collection<Task> deps) ;
// 
//     /* Checks whether runtime has enough tasks to process. */
//     public boolean parallelize(Task t);
// 
//     /* Creates a new data group object */
//     public DataGroup createDataGroup() ;
//     /* Creates a new Blocking task */
//     public BlockingTask createBlockingTask(Body b, short hints) ;
//     /* Creates a new NonBlocking task */
//     public NonBlockingTask createNonBlockingTask(Body b, short hints) ;
//     /* Creates a new Atomic task */
//     public AtomicTask createAtomicTask(Body b, DataGroup g, short hints) ;
// 
//     /* Return executor service abstraction for this runtime object */
//     public ExecutorService getExecutorService();
//     
//     /* Add/Remove error handlers */
//     public void addErrorHandler(ErrorHandler eh);
//     public void removeErrorHandler(ErrorHandler eh);
//     
//     /* Returns an estimation of how many tasks were created. */
// 	public int getTaskCount();
// }
// 
// Path: src/aeminium/runtime/Task.java
// public interface Task {
// 	public void setResult(Object value);
// 	public Object getResult();
// 	
// }
// 
// Path: src/aeminium/runtime/implementations/Factory.java
// public class Factory {
// 	protected static Runtime rt;
// 
// 	/**
// 	 * Prohibit Factory instantiation.
// 	 */
// 	protected Factory() {} 
// 
// 	/**
// 	 * Returns a new 'default' runtime object.
// 	 * @return
// 	 */
// 	public final static Runtime getRuntime() {
// 		//return getRuntime(Configuration.getImplementation());
// 		if ( rt == null ) {
// 			synchronized (Factory.class) {
// 				if ( Configuration.getImplementation().equals("default")) {
// 					rt = new ImplicitWorkStealingRuntime();
// 				} else {
// 					// try to load runtime from specified class 
// 					ClassLoader cl = Factory.class.getClassLoader();
// 					try {
// 						Class<?> klazz = cl.loadClass(Configuration.getImplementation());
// 						Object obj = klazz.newInstance();
// 						rt = (Runtime)obj;
// 					} catch (ClassNotFoundException e) {
// 						throw new Error("Cannot load runtime class : " + Configuration.getImplementation(),e);
// 					} catch (InstantiationException e) {
// 						throw new Error("Cannot instantiate class : " + Configuration.getImplementation(),e);
// 					} catch (IllegalAccessException e) {
// 						throw new Error("Cannot access class : " + Configuration.getImplementation(),e);
// 					}
// 				}
// 			}
// 		}
// 		return rt;
// 	}	
// }


import aeminium.runtime.implementations.Factory;
import aeminium.runtime.Body;
import aeminium.runtime.Runtime;
import aeminium.runtime.Task;
			Task root = creatTaskWithChildren(rt, level, level, fanout);
			rt.schedule(root, Runtime.NO_PARENT, Runtime.NO_DEPS);
			
			rt.shutdown();		
			long end = System.nanoTime();
			
			String result = String.format("Level %3d in %12d ns.", level, (end-start));
			reporter.reportLn(result);

	}

	public Task creatTaskWithChildren(final Runtime rt, final int level, final int MAX_LEVEL, final int fanout) {
		return rt.createNonBlockingTask(new Body() {
			
			@Override
			public void execute(Runtime rt, Task current) {
//				StringBuilder sb = new StringBuilder();
//				for ( int i =  0; i < (MAX_LEVEL - level) ; i++) {
//					sb.append(" ");
//				}
//				sb.append("Task@level"+level);
//				System.out.println(sb.toString());
				
				if ( 0 < level ) {
					for ( int i = 0; i < fanout; i++ ) {
						Task childTask = creatTaskWithChildren(rt, level-1, MAX_LEVEL, fanout);
						rt.schedule(childTask, current, Runtime.NO_DEPS);
					}
				}
			}
// Path: src/aeminium/runtime/Body.java
// public interface Body {
// 	/**
// 	 * This method contains the code of the body, that is executed by the task. 
// 	 * 
// 	 * @param current Reference to the associated task object.
// 	 */
//     public void execute(final Runtime rt, final Task current) throws Exception;
// }
// 
// Path: src/aeminium/runtime/Runtime.java
// public interface Runtime {
//     /* Global constants for default values */
//     public final static Collection<Task> NO_DEPS = new ArrayList<Task>() {
// 		private static final long serialVersionUID = 1852797887380877437L;
// 
// 		@Override 
// 		public String toString() {
// 			return "NO_DEPS"; 
// 		}
// 	};
//     public final static short NO_HINTS = Hints.NO_HINTS;
//     public final static Task NO_PARENT = new Task() {
// 		@Override
// 		public void setResult(Object value) {
// 			throw new Error("Cannot set result on NO_PARENT");
// 		}
// 
// 		@Override
// 		public Object getResult() {
// 			throw new Error("Cannot get result from NO_PARENT");
// 		}
// 		
// 		@Override
// 		public String toString() {
// 			return "NO_PARENT";
// 		}
// 	};
// 	
//     /* Initializes runtime. Should be called upon program start. */
//     public void init() ;
//     /* 
//      * Waits until all tasks are executed and frees
//      * all allocated resources. 
//      * Should be called at the end of the program. 
//      */
//     public void shutdown();
//     /* Waits until all tasks have been processed */
//     public void waitToEmpty();
//     /* 
//      * Submits a task for execution, providing the parent task as well
//      * as its dependencies.
//      *  */
//     public void schedule(Task task, Task parent, Collection<Task> deps) ;
// 
//     /* Checks whether runtime has enough tasks to process. */
//     public boolean parallelize(Task t);
// 
//     /* Creates a new data group object */
//     public DataGroup createDataGroup() ;
//     /* Creates a new Blocking task */
//     public BlockingTask createBlockingTask(Body b, short hints) ;
//     /* Creates a new NonBlocking task */
//     public NonBlockingTask createNonBlockingTask(Body b, short hints) ;
//     /* Creates a new Atomic task */
//     public AtomicTask createAtomicTask(Body b, DataGroup g, short hints) ;
// 
//     /* Return executor service abstraction for this runtime object */
//     public ExecutorService getExecutorService();
//     
//     /* Add/Remove error handlers */
//     public void addErrorHandler(ErrorHandler eh);
//     public void removeErrorHandler(ErrorHandler eh);
//     
//     /* Returns an estimation of how many tasks were created. */
// 	public int getTaskCount();
// }
// 
// Path: src/aeminium/runtime/Task.java
// public interface Task {
// 	public void setResult(Object value);
// 	public Object getResult();
// 	
// }
// 
// Path: src/aeminium/runtime/implementations/Factory.java
// public class Factory {
// 	protected static Runtime rt;
// 
// 	/**
// 	 * Prohibit Factory instantiation.
// 	 */
// 	protected Factory() {} 
// 
// 	/**
// 	 * Returns a new 'default' runtime object.
// 	 * @return
// 	 */
// 	public final static Runtime getRuntime() {
// 		//return getRuntime(Configuration.getImplementation());
// 		if ( rt == null ) {
// 			synchronized (Factory.class) {
// 				if ( Configuration.getImplementation().equals("default")) {
// 					rt = new ImplicitWorkStealingRuntime();
// 				} else {
// 					// try to load runtime from specified class 
// 					ClassLoader cl = Factory.class.getClassLoader();
// 					try {
// 						Class<?> klazz = cl.loadClass(Configuration.getImplementation());
// 						Object obj = klazz.newInstance();
// 						rt = (Runtime)obj;
// 					} catch (ClassNotFoundException e) {
// 						throw new Error("Cannot load runtime class : " + Configuration.getImplementation(),e);
// 					} catch (InstantiationException e) {
// 						throw new Error("Cannot instantiate class : " + Configuration.getImplementation(),e);
// 					} catch (IllegalAccessException e) {
// 						throw new Error("Cannot access class : " + Configuration.getImplementation(),e);
// 					}
// 				}
// 			}
// 		}
// 		return rt;
// 	}	
// }


// Path: src/aeminium/runtime/tools/benchmark/ChildTaskBenchmark.java
import aeminium.runtime.implementations.Factory;
import aeminium.runtime.Body;
import aeminium.runtime.Runtime;
import aeminium.runtime.Task;

			Task root = creatTaskWithChildren(rt, level, level, fanout);
			rt.schedule(root, Runtime.NO_PARENT, Runtime.NO_DEPS);
			
			rt.shutdown();		
			long end = System.nanoTime();
			
			String result = String.format("Level %3d in %12d ns.", level, (end-start));
			reporter.reportLn(result);

	}

	public Task creatTaskWithChildren(final Runtime rt, final int level, final int MAX_LEVEL, final int fanout) {
		return rt.createNonBlockingTask(new Body() {
			
			@Override
			public void execute(Runtime rt, Task current) {
//				StringBuilder sb = new StringBuilder();
//				for ( int i =  0; i < (MAX_LEVEL - level) ; i++) {
//					sb.append(" ");
//				}
//				sb.append("Task@level"+level);
//				System.out.println(sb.toString());
				
				if ( 0 < level ) {
					for ( int i = 0; i < fanout; i++ ) {
						Task childTask = creatTaskWithChildren(rt, level-1, MAX_LEVEL, fanout);
						rt.schedule(childTask, current, Runtime.NO_DEPS);
					}
				}
			}
		}, Runtime.NO_HINTS);