// Path: awex-core/src/main/java/com/raycoarana/awex/state/WorkerState.java
// enum State {
//     /**
//      * State for a worker which has not yet started.
//      */
//     NEW,
// 
//     /**
//      * State for a runnable worker.  A worker in the runnable
//      * state is executing in the Java virtual machine but it may
//      * be waiting for other resources from the operating system
//      * such as processor.
//      */
//     RUNNABLE,
// 
//     /**
//      * State for a worker blocked waiting for a monitor lock.
//      * The worker in the blocked state is waiting for a monitor lock
//      * to enter a synchronized block/method or
//      * reenter a synchronized block/method after calling
//      * {@link Object#wait() Object.wait}.
//      */
//     BLOCKED,
// 
//     /**
//      * State for a waiting worker.
//      * Worker is in the waiting state due to calling one of the
//      * following methods:
//      * <ul>
//      * <li>{@link Object#wait() Object.wait} with no timeout</li>
//      * <li>{@link Thread#join() Thread.join} with no timeout</li>
//      * <li>{@link LockSupport#park() LockSupport.park}</li>
//      * </ul>
//      *
//      * <p>A worker in the waiting state is waiting for another thread to
//      * perform a particular action.
//      * </p>
//      * For example, the worker thread that has called <tt>Object.wait()</tt>
//      * on an object is waiting for another thread to call
//      * <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on
//      * that object. The worker thread that has called <tt>Thread.join()</tt>
//      * is waiting for a specified thread to terminate.
//      */
//     WAITING,
// 
//     /**
//      * State for a waiting worker with a specified waiting time.
//      * The worker is in the timed waiting state due to calling one of
//      * the following methods with a specified positive waiting time:
//      * <ul>
//      * <li>{@link Thread#sleep Thread.sleep}</li>
//      * <li>{@link Object#wait(long) Object.wait} with timeout</li>
//      * <li>{@link Thread#join(long) Thread.join} with timeout</li>
//      * <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
//      * <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
//      * </ul>
//      */
//     TIMED_WAITING,
// 
//     /**
//      * State for terminated worker. No more tasks will be executed by this worker.
//      */
//     TERMINATED,
// 
//     /**
//      * State for a worker waiting for the next task.
//      * Worker is in waiting for next task state when the worker is waiting for next
//      * tasks to be queue.
//      */
//     WAITING_FOR_NEXT_TASK
// }
// 
// Path: awex-core/src/main/java/com/raycoarana/awex/state/WorkerStateImpl.java
// public class WorkerStateImpl implements WorkerState {
// 
//     private int mId;
//     private State mState;
//     private Task mCurrentTask;
//     private long mLastTimeActive;
// 
//     private final static ObjectPool<WorkerStateImpl> sObjectPool = new ObjectPool<>(30);
// 
//     public static WorkerStateImpl get(int id, State state, Task currentTask, long lastTimeActive) {
//         WorkerStateImpl workerState;
//         synchronized (sObjectPool) {
//             workerState = sObjectPool.acquire();
//             if (workerState == null) {
//                 workerState = new WorkerStateImpl();
//             }
//             workerState.mId = id;
//             workerState.mState = state;
//             workerState.mCurrentTask = currentTask;
//             workerState.mLastTimeActive = lastTimeActive;
//         }
//         return workerState;
//     }
// 
//     private WorkerStateImpl() {
//     }
// 
//     @Override
//     public int getId() {
//         return mId;
//     }
// 
//     @Override
//     public State getState() {
//         return mState;
//     }
// 
//     @Override
//     public Task getCurrentTask() {
//         return mCurrentTask;
//     }
// 
//     @Override
//     public long getLastTimeActive() {
//         return mLastTimeActive;
//     }
// 
//     public void recycle() {
//         mCurrentTask = null;
//         synchronized (sObjectPool) {
//             sObjectPool.release(this);
//         }
//     }
// 
//     public void toString(StringBuilder stringBuilder) {
//         stringBuilder.append("{/*Worker*/ id: ")
//                 .append(mId)
//                 .append(", state: ")
//                 .append(mState)
//                 .append(", lastTimeActive: ")
//                 .append(mLastTimeActive)
//                 .append(", currentTask: ");
//         if (mCurrentTask != null) {
//             mCurrentTask.toString(stringBuilder);
//         } else {
//             stringBuilder.append("null");
//         }
//         stringBuilder.append(" }");
//     }
// 
//     @Override
//     public String toString() {
//         StringBuilder stringBuilder = new StringBuilder();
//         toString(stringBuilder);
//         return stringBuilder.toString();
//     }
// 
// }


import com.raycoarana.awex.state.WorkerState.State;
import com.raycoarana.awex.state.WorkerStateImpl;
            mLogger.v("Worker " + mId + " starting...");
        }
        try {
            while (!mDie) {
                try {
                    Task newTask = mWorkQueue.take(this);
                    synchronized (this) {
                        mCurrentTask = newTask;
                        mExecutingTask = true;
                        mLastTimeActive = mCurrentTask != null ? System.nanoTime() / 10000000 : mLastTimeActive;
                    }
                    if (mCurrentTask != null) {
                        long taskId = mCurrentTask.getId();
                        if (mLogger.isEnabled()) {
                            mLogger.v("Worker " + mId + " start executing task " + taskId);
                        }
                        mCurrentTask.execute();
                        if (mLogger.isEnabled()) {
                            mLogger.v("Worker " + mId + " ends executing task " + taskId);
                        }
                    }
                } catch (InterruptedException ex) {
                    return;
                } finally {
                    Task executedTask = mCurrentTask;
                    synchronized (this) {
                        mCurrentTask = null;
                        mExecutingTask = false;
                    }
                    if (executedTask != null) {
// Path: awex-core/src/main/java/com/raycoarana/awex/state/WorkerState.java
// enum State {
//     /**
//      * State for a worker which has not yet started.
//      */
//     NEW,
// 
//     /**
//      * State for a runnable worker.  A worker in the runnable
//      * state is executing in the Java virtual machine but it may
//      * be waiting for other resources from the operating system
//      * such as processor.
//      */
//     RUNNABLE,
// 
//     /**
//      * State for a worker blocked waiting for a monitor lock.
//      * The worker in the blocked state is waiting for a monitor lock
//      * to enter a synchronized block/method or
//      * reenter a synchronized block/method after calling
//      * {@link Object#wait() Object.wait}.
//      */
//     BLOCKED,
// 
//     /**
//      * State for a waiting worker.
//      * Worker is in the waiting state due to calling one of the
//      * following methods:
//      * <ul>
//      * <li>{@link Object#wait() Object.wait} with no timeout</li>
//      * <li>{@link Thread#join() Thread.join} with no timeout</li>
//      * <li>{@link LockSupport#park() LockSupport.park}</li>
//      * </ul>
//      *
//      * <p>A worker in the waiting state is waiting for another thread to
//      * perform a particular action.
//      * </p>
//      * For example, the worker thread that has called <tt>Object.wait()</tt>
//      * on an object is waiting for another thread to call
//      * <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on
//      * that object. The worker thread that has called <tt>Thread.join()</tt>
//      * is waiting for a specified thread to terminate.
//      */
//     WAITING,
// 
//     /**
//      * State for a waiting worker with a specified waiting time.
//      * The worker is in the timed waiting state due to calling one of
//      * the following methods with a specified positive waiting time:
//      * <ul>
//      * <li>{@link Thread#sleep Thread.sleep}</li>
//      * <li>{@link Object#wait(long) Object.wait} with timeout</li>
//      * <li>{@link Thread#join(long) Thread.join} with timeout</li>
//      * <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
//      * <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
//      * </ul>
//      */
//     TIMED_WAITING,
// 
//     /**
//      * State for terminated worker. No more tasks will be executed by this worker.
//      */
//     TERMINATED,
// 
//     /**
//      * State for a worker waiting for the next task.
//      * Worker is in waiting for next task state when the worker is waiting for next
//      * tasks to be queue.
//      */
//     WAITING_FOR_NEXT_TASK
// }
// 
// Path: awex-core/src/main/java/com/raycoarana/awex/state/WorkerStateImpl.java
// public class WorkerStateImpl implements WorkerState {
// 
//     private int mId;
//     private State mState;
//     private Task mCurrentTask;
//     private long mLastTimeActive;
// 
//     private final static ObjectPool<WorkerStateImpl> sObjectPool = new ObjectPool<>(30);
// 
//     public static WorkerStateImpl get(int id, State state, Task currentTask, long lastTimeActive) {
//         WorkerStateImpl workerState;
//         synchronized (sObjectPool) {
//             workerState = sObjectPool.acquire();
//             if (workerState == null) {
//                 workerState = new WorkerStateImpl();
//             }
//             workerState.mId = id;
//             workerState.mState = state;
//             workerState.mCurrentTask = currentTask;
//             workerState.mLastTimeActive = lastTimeActive;
//         }
//         return workerState;
//     }
// 
//     private WorkerStateImpl() {
//     }
// 
//     @Override
//     public int getId() {
//         return mId;
//     }
// 
//     @Override
//     public State getState() {
//         return mState;
//     }
// 
//     @Override
//     public Task getCurrentTask() {
//         return mCurrentTask;
//     }
// 
//     @Override
//     public long getLastTimeActive() {
//         return mLastTimeActive;
//     }
// 
//     public void recycle() {
//         mCurrentTask = null;
//         synchronized (sObjectPool) {
//             sObjectPool.release(this);
//         }
//     }
// 
//     public void toString(StringBuilder stringBuilder) {
//         stringBuilder.append("{/*Worker*/ id: ")
//                 .append(mId)
//                 .append(", state: ")
//                 .append(mState)
//                 .append(", lastTimeActive: ")
//                 .append(mLastTimeActive)
//                 .append(", currentTask: ");
//         if (mCurrentTask != null) {
//             mCurrentTask.toString(stringBuilder);
//         } else {
//             stringBuilder.append("null");
//         }
//         stringBuilder.append(" }");
//     }
// 
//     @Override
//     public String toString() {
//         StringBuilder stringBuilder = new StringBuilder();
//         toString(stringBuilder);
//         return stringBuilder.toString();
//     }
// 
// }


// Path: awex-core/src/main/java/com/raycoarana/awex/Worker.java
import com.raycoarana.awex.state.WorkerState.State;
import com.raycoarana.awex.state.WorkerStateImpl;

            mLogger.v("Worker " + mId + " starting...");
        }
        try {
            while (!mDie) {
                try {
                    Task newTask = mWorkQueue.take(this);
                    synchronized (this) {
                        mCurrentTask = newTask;
                        mExecutingTask = true;
                        mLastTimeActive = mCurrentTask != null ? System.nanoTime() / 10000000 : mLastTimeActive;
                    }
                    if (mCurrentTask != null) {
                        long taskId = mCurrentTask.getId();
                        if (mLogger.isEnabled()) {
                            mLogger.v("Worker " + mId + " start executing task " + taskId);
                        }
                        mCurrentTask.execute();
                        if (mLogger.isEnabled()) {
                            mLogger.v("Worker " + mId + " ends executing task " + taskId);
                        }
                    }
                } catch (InterruptedException ex) {
                    return;
                } finally {
                    Task executedTask = mCurrentTask;
                    synchronized (this) {
                        mCurrentTask = null;
                        mExecutingTask = false;
                    }
                    if (executedTask != null) {
                        mListener.onTaskFinished(executedTask);