/*
 * Java Genetic Algorithm Library (@__identifier__@).
 * Copyright (c) @__year__@ Franz Wilhelmstötter
 *
 * Licensed 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.
 *
 * Author:
 *    Franz Wilhelmstötter (franz.wilhelmstoetter@gmx.at)
 */
package org.jenetics.util;

import static java.util.Objects.requireNonNull;

import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ForkJoinPool;

import org.jenetics.internal.util.ScopedExecutor;
import org.jenetics.internal.util.ScopedExecutorProxy;
import org.jenetics.internal.util.ScopedExecutorService;
import org.jenetics.internal.util.ScopedForkJoinPool;
import org.jenetics.internal.util.Context;

/**
 * [code]
 * try (Scoped<Executor> executor = Concurrent.scope()) {
 *     executor.get().execute(task1);
 *     executor.get().execute(task2);
 * }
 * [/code]
 *
 * @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a>
 * @since 2.0
 * @version 2.0 &mdash; <em>$Date: 2014-03-16 $</em>
 */
public abstract class Concurrent {

	private static final ForkJoinPool DEFAULT = new ForkJoinPool(
		Math.max(Runtime.getRuntime().availableProcessors() - 1, 1)
	);

	private static final Executor SERIAL_EXECUTOR = new Executor() {
		@Override
		public void execute(final Runnable command) {
			command.run();
		}
	};

	private static final Context<Executor> CONTEXT =
		new Context<Executor>(DEFAULT);

	/**
	 * Set the executor object to use for concurrent actions.
	 *
	 * @param executor the executor object to use.
	 * @throws java.lang.NullPointerException if the given {@code executor} is
	 *         {@code null}.
	 */
	public static void setExecutor(final Executor executor) {
		CONTEXT.set(requireNonNull(executor, "Executor must not be null."));
	}

	/**
	 * Return the currently used executor object.
	 *
	 * @return the currently used thread pool.
	 */
	public static Executor getExecutor() {
		return CONTEXT.get();
	}

	/**
	 *
	 * @return
	 */
	public static Scoped<Executor> scope() {
		return newScope(CONTEXT.get());
	}

	public static Scoped<Executor> serial() {
		return CONTEXT.scope(SERIAL_EXECUTOR);
	}

	public static Scoped<Executor> scope(final Executor executor) {
		final Scoped<Executor> scope = CONTEXT.scope(requireNonNull(executor));
		final Scoped<Executor> exec = newScope(executor);

		return new ScopedExecutorProxy(scope, exec);
	}

	public static void reset() {
		CONTEXT.reset();
	}

	private static Scoped<Executor> newScope(final Executor executor) {
		if (executor instanceof ForkJoinPool) {
			return new ScopedForkJoinPool((ForkJoinPool)executor);
		} else if (executor instanceof ExecutorService) {
			return new ScopedExecutorService((ExecutorService)executor);
		} else {
			return new ScopedExecutor(executor);
		}
	}

}

@@ -933,24 +933,67 @@
 kJoinPool;%0A%0A
+import org.jenetics.internal.util.Context;%0A
 import org.j
@@ -1199,51 +1199,8 @@
 ool;
-%0Aimport org.jenetics.internal.util.Context;
 %0A%0A/*
@@ -1528,22 +1528,62 @@
 lic 
-abstract class
+final class Concurrent extends StaticObject %7B%0A%09private
  Con
@@ -1589,18 +1589,21 @@
 ncurrent
+()
  %7B
+%7D
 %0A%0A%09priva
@@ -2506,193 +2506,832 @@
 %0A%09 *
-%0A%09 * @return%0A%09 */%0A%09public static Scoped%3CExecutor%3E scope() %7B%0A%09%09return newScope(CONTEXT.get());%0A%09%7D%0A%0A%09public static Scoped%3CExecutor%3E serial() %7B%0A%09%09return CONTEXT.scope(SERIAL_EXECUTOR);%0A%09%7D%0A
+ Open a new executor scope with the currently set%0A%09 * %7B@link java.util.concurrent.Executor%7D.%0A%09 *%0A%09 * @return a new executor with the currently se %7B@code Executor%7D.%0A%09 */%0A%09public static Scoped%3CExecutor%3E scope() %7B%0A%09%09return newScope(CONTEXT.get());%0A%09%7D%0A%0A%09/**%0A%09 * Open a new executor scope, where all tasks are executed in the main%0A%09 * thread.%0A%09 *%0A%09 * @return a new %3Ci%3Eserial%3C/i%3E executor scope.%0A%09 */%0A%09public static Scoped%3CExecutor%3E serial() %7B%0A%09%09return CONTEXT.scope(SERIAL_EXECUTOR);%0A%09%7D%0A%0A%09/**%0A%09 * Open a new executor scope with the given %7B@code executor%7D. When this%0A%09 * scope is %3Ci%3Eclosed%3C/i%3E, the original executor is restored.%0A%09 *%0A%09 * @param executor the executor used for the new scope.%0A%09 * @return a new executor scope%0A%09 * @throws java.lang.NullPointerException if the given %7B@code executor%7D is%0A%09 *         %7B@code null%7D.%0A%09 */
 %0A%09pu
@@ -3570,16 +3570,74 @@
 c);%0A%09%7D%0A%0A
+%09/**%0A%09 * Set the used executor to the default value.%0A%09 */%0A
 %09public 

Add javadoc.