// Path: api/src/main/java/com/asyncj/core/api/ActorManager.java
// public class ActorManager {
// 
// 
//     private BlockingQueue<ActorMessage> queue = new LinkedBlockingQueue<ActorMessage>();
// 
//     private Map<Object, Proxy> actorToProxy = (new LinkedHashMap<Object, Proxy>());
// 
//     public ActorManager() {
// 
//         int availableProcessors = Runtime.getRuntime().availableProcessors() * 20;
// 
//         ActorManagerThread actorManagerThread = new ActorManagerThread(queue);
//         for (int i = 0; i < availableProcessors; i++) {
//             actorManagerThread.addNewActorThread();
//         }
// 
//         actorManagerThread.start();
//     }
// 
// 
//     @SuppressWarnings("unchecked")
//     public synchronized  <T> T createActor(Object obj) {
//         MethodHandler h = new MethodHandler(obj);
//         T t = (T) Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), h);
//         actorToProxy.put(obj, (Proxy) t);
//         return t;
//     }
// 
//     public synchronized  <T> List<T> createActors(Object obj, int count) {
//         List<T> ts = new ArrayList<T>();
//         for (int i = 0; i < count; i++) {
//             ts.add(this.<T>createActor(obj));
//         }
//         return ts;
//     }
// 
//     @SuppressWarnings("unchecked")
//     public <T> T getReference(T actor1) {
//         return (T) actorToProxy.get(actor1);
//     }
// 
//     public void unblockResult(Object actor1) {
//         Proxy proxy = (Proxy) getReference(actor1);
//         ((MethodHandler) Proxy.getInvocationHandler(proxy)).unblockResult();
//     }
// 
//     class MethodHandler implements InvocationHandler {
// 
//         private Object obj;
// 
//         private final Object lock = new Object();
// 
//         public MethodHandler(Object obj) {
//             this.obj = obj;
//         }
// 
//         @Override
//         public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 
//             if ("hashCode".equals(method.getName()) ) {
//                 return obj.hashCode();
//             }
// 
//             if ("equals".equals(method.getName()) ) {
//                 return obj.equals(args);
//             }
// 
//             if ("toString".equals(method.getName()) ) {
//                 return obj.toString();
//             }
//             // a method invocation will send the message to a blocking queue
//             int i=0;
//             if (args != null) {
//                 for (Object arg : args) {
//                     Proxy proxy1 = actorToProxy.get(arg);
//                     if (proxy1 != null) {
//                         args[i] = proxy1;
//                     }
//                     i++;
//                 }
//             }
// 
//             Class<?> returnType = method.getReturnType();
//             if ("void".equals(returnType.getName())) {
//                 queue.put(new ActorMessage(ActorMessage.METHOD_CALL, obj, method, args));
//                 return null;
//             }
//             else {
// 
//                 //if the return class is an actor interface then return a new instance of the proxy
//                 //to the user and associate it with the current proxy/actor.
//                 //the proxy should send all messages inside with a type METHOD_RESULT
//                 // and when the actor thread will execute the
//                 // method which will return the result of the actual actor, then the actor thread will send
//                 // a message to the Actor Manager Thread. The AMT will start sending messages to the new actor...
//                 //when the actor will be instantiated later it should receive all messages
//                 //that has been sent to it before
// 
//                 //block the current thread and wait for the value from a future object
//                 synchronized (lock) {
//                     lock.wait();
//                     return method.invoke(obj, args);
//                 }
//             }
//         }
// 
//         public void unblockResult() {
//             synchronized (lock) {
//                 lock.notify();
//             }
//         }
// 
//     }
// }


import com.asyncj.core.api.ActorManager;
        this.workLoad = workLoad;
    }

    public void pong(ForkJoinExample.Actor2 actor2, String s) {
        count++;

        if (count < n) {
            if (count % 100000 == 0)
                System.out.println(count + " pings from - " + s);
            actor2.ping(this, count);
        }
        else {
            System.out.println("final count = " + count);
            if (parentActor1 != null) {
                parentActor1.incCount(count);
            }
        }
    }

    @Override
    public void incCount(int count) {
        incTimes++;
        this.count += count;
        System.out.println("sub count = " + this.count);
        if (incTimes >= 5 && parentActor1 != null) {
            parentActor1.incCount(this.count);
        }
    }

    @Override
// Path: api/src/main/java/com/asyncj/core/api/ActorManager.java
// public class ActorManager {
// 
// 
//     private BlockingQueue<ActorMessage> queue = new LinkedBlockingQueue<ActorMessage>();
// 
//     private Map<Object, Proxy> actorToProxy = (new LinkedHashMap<Object, Proxy>());
// 
//     public ActorManager() {
// 
//         int availableProcessors = Runtime.getRuntime().availableProcessors() * 20;
// 
//         ActorManagerThread actorManagerThread = new ActorManagerThread(queue);
//         for (int i = 0; i < availableProcessors; i++) {
//             actorManagerThread.addNewActorThread();
//         }
// 
//         actorManagerThread.start();
//     }
// 
// 
//     @SuppressWarnings("unchecked")
//     public synchronized  <T> T createActor(Object obj) {
//         MethodHandler h = new MethodHandler(obj);
//         T t = (T) Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), h);
//         actorToProxy.put(obj, (Proxy) t);
//         return t;
//     }
// 
//     public synchronized  <T> List<T> createActors(Object obj, int count) {
//         List<T> ts = new ArrayList<T>();
//         for (int i = 0; i < count; i++) {
//             ts.add(this.<T>createActor(obj));
//         }
//         return ts;
//     }
// 
//     @SuppressWarnings("unchecked")
//     public <T> T getReference(T actor1) {
//         return (T) actorToProxy.get(actor1);
//     }
// 
//     public void unblockResult(Object actor1) {
//         Proxy proxy = (Proxy) getReference(actor1);
//         ((MethodHandler) Proxy.getInvocationHandler(proxy)).unblockResult();
//     }
// 
//     class MethodHandler implements InvocationHandler {
// 
//         private Object obj;
// 
//         private final Object lock = new Object();
// 
//         public MethodHandler(Object obj) {
//             this.obj = obj;
//         }
// 
//         @Override
//         public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 
//             if ("hashCode".equals(method.getName()) ) {
//                 return obj.hashCode();
//             }
// 
//             if ("equals".equals(method.getName()) ) {
//                 return obj.equals(args);
//             }
// 
//             if ("toString".equals(method.getName()) ) {
//                 return obj.toString();
//             }
//             // a method invocation will send the message to a blocking queue
//             int i=0;
//             if (args != null) {
//                 for (Object arg : args) {
//                     Proxy proxy1 = actorToProxy.get(arg);
//                     if (proxy1 != null) {
//                         args[i] = proxy1;
//                     }
//                     i++;
//                 }
//             }
// 
//             Class<?> returnType = method.getReturnType();
//             if ("void".equals(returnType.getName())) {
//                 queue.put(new ActorMessage(ActorMessage.METHOD_CALL, obj, method, args));
//                 return null;
//             }
//             else {
// 
//                 //if the return class is an actor interface then return a new instance of the proxy
//                 //to the user and associate it with the current proxy/actor.
//                 //the proxy should send all messages inside with a type METHOD_RESULT
//                 // and when the actor thread will execute the
//                 // method which will return the result of the actual actor, then the actor thread will send
//                 // a message to the Actor Manager Thread. The AMT will start sending messages to the new actor...
//                 //when the actor will be instantiated later it should receive all messages
//                 //that has been sent to it before
// 
//                 //block the current thread and wait for the value from a future object
//                 synchronized (lock) {
//                     lock.wait();
//                     return method.invoke(obj, args);
//                 }
//             }
//         }
// 
//         public void unblockResult() {
//             synchronized (lock) {
//                 lock.notify();
//             }
//         }
// 
//     }
// }


// Path: api/src/test/java/com/asyncj/core/api/examples/forkjoin/Actor1Impl.java
import com.asyncj.core.api.ActorManager;

        this.workLoad = workLoad;
    }

    public void pong(ForkJoinExample.Actor2 actor2, String s) {
        count++;

        if (count < n) {
            if (count % 100000 == 0)
                System.out.println(count + " pings from - " + s);
            actor2.ping(this, count);
        }
        else {
            System.out.println("final count = " + count);
            if (parentActor1 != null) {
                parentActor1.incCount(count);
            }
        }
    }

    @Override
    public void incCount(int count) {
        incTimes++;
        this.count += count;
        System.out.println("sub count = " + this.count);
        if (incTimes >= 5 && parentActor1 != null) {
            parentActor1.incCount(this.count);
        }
    }

    @Override
    public void startPings(ActorManager actorManager, int m) {