You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@edgent.apache.org by dl...@apache.org on 2016/07/21 13:17:47 UTC

[46/54] [abbrv] [partial] incubator-quarks git commit: add "org.apache." prefix to edgent package names

http://git-wip-us.apache.org/repos/asf/incubator-quarks/blob/a129aa16/api/execution/src/main/java/org/apache/edgent/execution/services/ServiceContainer.java
----------------------------------------------------------------------
diff --git a/api/execution/src/main/java/org/apache/edgent/execution/services/ServiceContainer.java b/api/execution/src/main/java/org/apache/edgent/execution/services/ServiceContainer.java
new file mode 100644
index 0000000..fc4690f
--- /dev/null
+++ b/api/execution/src/main/java/org/apache/edgent/execution/services/ServiceContainer.java
@@ -0,0 +1,125 @@
+/*
+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 org.apache.edgent.execution.services;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.edgent.execution.Job;
+import org.apache.edgent.function.BiConsumer;
+
+/**
+ * Provides a container for services.
+ * <p>
+ * The current implementation does not downcast the provided service class
+ * when searching for an appropriate service implementation.  For example:
+ * <pre>
+ *   class Derived extends Base {}
+ * 
+ *   serviceContainer.add(Derived.class, instanceOfDerived);
+ * 
+ *   // Searching for the base class returns null
+ *   assert(null == serviceContainer.get(Base.class, instanceOfDerived));
+ * </pre>
+ */
+public class ServiceContainer {
+    private final Map<Class<?>, Object> services;
+    private final Set<BiConsumer<String,String>> cleaners;
+
+    public ServiceContainer() {
+        this.services = Collections.synchronizedMap(new HashMap<>());
+        cleaners = Collections.synchronizedSet(new HashSet<>());
+    }
+
+    /**
+     * Adds the specified service to this {@code ServiceContainer}.
+     * <p>
+     * Associates the specified service with the service class.  If the 
+     * container has previously contained a service for the class, 
+     * the old value is replaced by the specified value.
+     *
+     * @param <T> service class type
+     * @param serviceClass the class of service to add.
+     * @param service service to add to this container.
+     * @return the previous value associated with {@code serviceClass}, or
+     *         {@code null} if there was no registered mapping.
+     * @throws NullPointerException if the specified service class or 
+     *         service is null.
+     */
+    public <T> T addService(Class<T> serviceClass, T service) {
+        return serviceClass.cast(services.put(serviceClass, service));
+    }
+
+    /**
+     * Removes the specified service from this {@code ServiceContainer}.
+     *
+     * @param <T> service class type
+     * @param serviceClass the class of service to remove.
+     * @return the service previously associated with the service class, or
+     *         {@code null} if there was no registered service.
+     * @throws NullPointerException if the specified service class is null.
+     */
+    public <T> T removeService(Class<T> serviceClass) {
+        return serviceClass.cast(services.remove(serviceClass));
+    }
+
+    /**
+     * Returns the service to which the specified service class key is
+     * mapped, or {@code null} if this {@code ServiceContainer} contains no 
+     * service for that key.
+     * 
+     * @param <T> service class type
+     * @param serviceClass the class whose associated service is to be returned
+     * @return the service instance mapped to the specified service class, or
+     *         {@code null} if no service is registered for the class.
+     */
+    public <T> T getService(Class<T> serviceClass) {
+        return serviceClass.cast(services.get(serviceClass));
+    }
+    
+    /**
+     * Registers a new cleaner.
+     * <p>
+     * A cleaner is a hook which is invoked when the runtime
+     * closes an element of {@link Job}.
+     * When an element of job is closed {@code cleaner.accept(jobId, elementId)}
+     * is called where {@code jobId} is the {@link Job#getId() job identifier} and
+     * {@code elementId} is the unique identifier for the element.
+     * 
+     * @param cleaner The cleaner.
+     */
+    public void addCleaner(BiConsumer<String,String> cleaner) {
+        cleaners.add(cleaner);
+    }
+    
+    /**
+     * Invokes all the registered cleaners in the context of the specified 
+     * job and element.
+     * 
+     * @param jobId The job identifier.
+     * @param elementId The element identifier.
+     */
+    public void cleanOplet(String jobId, String elementId) {
+        for (BiConsumer<String,String> cleaner : cleaners)
+            cleaner.accept(jobId, elementId);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-quarks/blob/a129aa16/api/execution/src/main/java/org/apache/edgent/execution/services/package-info.java
----------------------------------------------------------------------
diff --git a/api/execution/src/main/java/org/apache/edgent/execution/services/package-info.java b/api/execution/src/main/java/org/apache/edgent/execution/services/package-info.java
new file mode 100644
index 0000000..1b3a313
--- /dev/null
+++ b/api/execution/src/main/java/org/apache/edgent/execution/services/package-info.java
@@ -0,0 +1,22 @@
+/*
+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.
+*/
+/**
+ * Execution services.
+ */
+package org.apache.edgent.execution.services;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-quarks/blob/a129aa16/api/execution/src/test/java/edgent/test/execution/ControlsTest.java
----------------------------------------------------------------------
diff --git a/api/execution/src/test/java/edgent/test/execution/ControlsTest.java b/api/execution/src/test/java/edgent/test/execution/ControlsTest.java
deleted file mode 100644
index ec1fc86..0000000
--- a/api/execution/src/test/java/edgent/test/execution/ControlsTest.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
-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 edgent.test.execution;
-
-import static edgent.execution.services.Controls.isControlServiceMBean;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import java.io.DataInput;
-import java.util.List;
-import java.util.concurrent.Callable;
-
-import org.junit.Test;
-
-import edgent.execution.mbeans.JobMXBean;
-
-public class ControlsTest {
-    
-    @Test
-    public void testNotValid() {
-        
-        // Not an interface
-        assertFalse(isControlServiceMBean(Object.class));
-        
-        // List extends anther
-        assertFalse(isControlServiceMBean(List.class));
-        
-        // Is parameterized
-        assertFalse(isControlServiceMBean(Callable.class));
-        
-        // Methods with unsupported signatures.
-        assertFalse(isControlServiceMBean(DataInput.class));  
-    }
-    @Test
-    public void testValid() {
-        assertTrue(isControlServiceMBean(Runnable.class));
-        
-        assertTrue(isControlServiceMBean(JobMXBean.class));
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-quarks/blob/a129aa16/api/execution/src/test/java/org/apache/edgent/test/execution/ControlsTest.java
----------------------------------------------------------------------
diff --git a/api/execution/src/test/java/org/apache/edgent/test/execution/ControlsTest.java b/api/execution/src/test/java/org/apache/edgent/test/execution/ControlsTest.java
new file mode 100644
index 0000000..2b42a7d
--- /dev/null
+++ b/api/execution/src/test/java/org/apache/edgent/test/execution/ControlsTest.java
@@ -0,0 +1,55 @@
+/*
+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 org.apache.edgent.test.execution;
+
+import static org.apache.edgent.execution.services.Controls.isControlServiceMBean;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.io.DataInput;
+import java.util.List;
+import java.util.concurrent.Callable;
+
+import org.apache.edgent.execution.mbeans.JobMXBean;
+import org.junit.Test;
+
+public class ControlsTest {
+    
+    @Test
+    public void testNotValid() {
+        
+        // Not an interface
+        assertFalse(isControlServiceMBean(Object.class));
+        
+        // List extends anther
+        assertFalse(isControlServiceMBean(List.class));
+        
+        // Is parameterized
+        assertFalse(isControlServiceMBean(Callable.class));
+        
+        // Methods with unsupported signatures.
+        assertFalse(isControlServiceMBean(DataInput.class));  
+    }
+    @Test
+    public void testValid() {
+        assertTrue(isControlServiceMBean(Runnable.class));
+        
+        assertTrue(isControlServiceMBean(JobMXBean.class));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-quarks/blob/a129aa16/api/function/src/main/java/edgent/function/BiConsumer.java
----------------------------------------------------------------------
diff --git a/api/function/src/main/java/edgent/function/BiConsumer.java b/api/function/src/main/java/edgent/function/BiConsumer.java
deleted file mode 100644
index 5e0518c..0000000
--- a/api/function/src/main/java/edgent/function/BiConsumer.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
-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 edgent.function;
-
-import java.io.Serializable;
-
-/**
- * Consumer function that takes two arguments.
- * @param <T> Type of the first function argument
- * @param <U> Type of the second function argument
- */
-public interface BiConsumer<T,U> extends Serializable {
-    
-    /**
-     * Consume the two arguments.
-     * @param t First function argument
-     * @param u Second function argument
-     */
-    void accept(T t, U u);
-}

http://git-wip-us.apache.org/repos/asf/incubator-quarks/blob/a129aa16/api/function/src/main/java/edgent/function/BiFunction.java
----------------------------------------------------------------------
diff --git a/api/function/src/main/java/edgent/function/BiFunction.java b/api/function/src/main/java/edgent/function/BiFunction.java
deleted file mode 100644
index 81ad4f9..0000000
--- a/api/function/src/main/java/edgent/function/BiFunction.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
-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 edgent.function;
-
-import java.io.Serializable;
-
-/**
- * Function that takes two arguments and returns a value.
- *
- * @param <T> Type of function's first argument
- * @param <U> Type of function's second argument
- * @param <R> Type of function return.
- */
-public interface BiFunction<T, U, R> extends Serializable {
-    
-    /**
-     * Apply a function to {@code t} and {@code u}.
-     * @param t First argument the function is applied to.
-     * @param u Second argument the function is applied to.
-     * @return Result of the function against {@code t} and {@code u}.
-     */
-    R apply(T t, U u);
-}

http://git-wip-us.apache.org/repos/asf/incubator-quarks/blob/a129aa16/api/function/src/main/java/edgent/function/Consumer.java
----------------------------------------------------------------------
diff --git a/api/function/src/main/java/edgent/function/Consumer.java b/api/function/src/main/java/edgent/function/Consumer.java
deleted file mode 100644
index fa5a40d..0000000
--- a/api/function/src/main/java/edgent/function/Consumer.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
-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 edgent.function;
-
-import java.io.Serializable;
-
-/**
- * Function that consumes a value.
- *
- * @param <T> Type of function argument.
- */
-public interface Consumer<T> extends Serializable {
-    
-    /**
-     * Apply the function to {@code value}.
-     * @param value Value function is applied to.
-     */
-    void accept(T value);
-}

http://git-wip-us.apache.org/repos/asf/incubator-quarks/blob/a129aa16/api/function/src/main/java/edgent/function/Function.java
----------------------------------------------------------------------
diff --git a/api/function/src/main/java/edgent/function/Function.java b/api/function/src/main/java/edgent/function/Function.java
deleted file mode 100644
index 7dbcf39..0000000
--- a/api/function/src/main/java/edgent/function/Function.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
-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 edgent.function;
-
-import java.io.Serializable;
-
-/**
- * Single argument function.
- * For example:
- * <UL>
- * <LI>
- * A function that doubles a value {@code v -> v * 2}
- * </LI>
- * <LI>
- * A function that trims a {@code String} {@code v -> v.trim()} or {@code v -> String::trim}
- * </LI>
- * </UL>
- *
- * @param <T> Type of function argument.
- * @param <R> Type of function return.
- */
-public interface Function<T, R> extends Serializable {
-    
-    /**
-     * Apply a function to {@code value}.
-     * @param value Value the function is applied to
-     * @return Result of the function against {@code value}.
-     */
-    R apply(T value);
-}

http://git-wip-us.apache.org/repos/asf/incubator-quarks/blob/a129aa16/api/function/src/main/java/edgent/function/Functions.java
----------------------------------------------------------------------
diff --git a/api/function/src/main/java/edgent/function/Functions.java b/api/function/src/main/java/edgent/function/Functions.java
deleted file mode 100644
index 9f802d9..0000000
--- a/api/function/src/main/java/edgent/function/Functions.java
+++ /dev/null
@@ -1,409 +0,0 @@
-/*
-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 edgent.function;
-
-import java.io.File;
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.util.HashSet;
-import java.util.Locale;
-import java.util.Set;
-import java.util.UUID;
-
-/**
- * Common functions and functional utilities.
- *
- */
-public class Functions {
-    
-    /**
-     * Single instance of the identity function.
-     */
-    private static final UnaryOperator<Object> IDENTITY = t -> t;
-    
-    /**
-     * Single instance of constant function that returns zero.
-     */
-    private static final Function<Object,Integer> ZERO = t -> 0;
-
-    
-    /**
-     * Returns the identity function that returns its single argument.
-     * @param <T> tuple type
-     * @return Identity function that returns its single argument.
-     */
-    @SuppressWarnings("unchecked")
-    public static <T> UnaryOperator<T> identity() {
-        return (UnaryOperator<T>) IDENTITY;
-    }
-    
-    /**
-     * Returns a constant function that returns zero (0).
-     * @param <T> tuple type
-     * @return Constant function that returns zero (0).
-     */
-    @SuppressWarnings("unchecked")
-    public static <T> Function<T,Integer> zero() {
-        return (Function<T, Integer>) ZERO;
-    }
-    
-    /**
-     * Returns a constant function that returns zero (0).
-     * This is identical to {@link #zero()} but is more
-     * readable when applied as a key function.
-     * @param <T> tuple type
-     * @return Constant function that returns zero (0).
-     */
-    public static <T> Function<T,Integer> unpartitioned() {
-        return zero();
-    }
-    
-    /**
-     * Close the function.
-     * If {@code function} is an instance of {@code AutoCloseable}
-     * then close is called, otherwise no action is taken.
-     * @param function Function to be closed.
-     * @throws Exception Error throwing function.
-     */
-    public static void closeFunction(Object function) throws Exception {
-        
-        AutoCloseable closeable = WrappedFunction.unwrap(AutoCloseable.class, function);
-        if (closeable != null)
-            closeable.close();
-    }
-    
-    /**
-     * Return a thread-safe version of a {@code Function} function.
-     * If the function is guaranteed to be immutable (stateless)
-     * then the function is returned, as it is thread safe,
-     * otherwise a wrapper is returned that grabs synchronization
-     * on {@code function} when calling {@link Function#apply(Object)}.
-     * <BR>
-     * If {@code function} implements {@code AutoCloseable} then
-     * the function is assumed to be stateful and a thread-safe
-     * version is returned.
-     * @param <T> source tuple type
-     * @param <R> result tuple type
-     * @param function Function to return a thread-safe version of.
-     * @return A thread-safe function
-     */
-    public static <T,R> Function<T,R> synchronizedFunction(final Function<T,R> function) {
-        if (isImmutable(function) && !(function instanceof AutoCloseable))
-            return function;
-        
-        // Return a function that is synchronized on the passed in function reference.
-        return new ThreadSafeFunction<T,R>(function);
-    }
-    
-    private static class ThreadSafeFunction<T,R> extends WrappedFunction<Function<T,R>> implements Function<T,R> {
-        private static final long serialVersionUID = 1L;
-
-        ThreadSafeFunction(Function<T,R> function) {
-            super(function);
-        }
-
-        @Override
-        public R apply(T value) {
-            final Function<T,R> function = f();
-            synchronized (function) {
-                return function.apply(value);
-            }
-        }
-    }
-    
-    /**
-     * Return a thread-safe version of a {@code Supplier} function.
-     * If the function is guaranteed to be immutable (stateless)
-     * then the function is returned, as it is thread safe,
-     * otherwise a wrapper is returned that grabs synchronization
-     * on {@code function} when calling {@link Supplier#get()}.
-     * <BR>
-     * If {@code function} implements {@code AutoCloseable} then
-     * the function is assumed to be stateful and a thread-safe
-     * version is returned.
-     * @param <T> tuple type
-     * @param function Function to return a thread-safe version of.
-     * @return A thread-safe function
-     */
-    public static <T> Supplier<T> synchronizedSupplier(final Supplier<T> function) {
-        if (isImmutable(function) && !(function instanceof AutoCloseable))
-            return function;
-        
-        // Return a function that is synchronized on the passed in function reference.
-        return new ThreadSafeSupplier<T>(function);
-    }
-
-    private static class ThreadSafeSupplier<T> extends WrappedFunction<Supplier<T>> implements Supplier<T> {
-        private static final long serialVersionUID = 1L;
-
-        ThreadSafeSupplier(Supplier<T> function) {
-            super(function);
-        }
-
-        @Override
-        public T get() {
-            final Supplier<T> function = f();
-            synchronized (function) {
-                return function.get();
-            }
-        }
-    }
-    
-    /**
-     * Return a thread-safe version of a {@code Consumer} function.
-     * If the function is guaranteed to be immutable (stateless)
-     * then the function is returned, as it is thread safe,
-     * otherwise a wrapper is returned that grabs synchronization
-     * on {@code function} when calling {@link Consumer#accept(Object)}.
-     * <BR>
-     * If {@code function} implements {@code AutoCloseable} then
-     * the function is assumed to be stateful and a thread-safe
-     * version is returned.
-     * @param <T> tuple type
-     * @param function Function to return a thread-safe version of.
-     * @return A thread-safe function
-     */
-    public static <T> Consumer<T> synchronizedConsumer(final Consumer<T> function) {
-        if (isImmutable(function) && !(function instanceof AutoCloseable))
-            return function;
-        
-        // Return a function that is synchronized on the passed in function reference.
-        return new ThreadSafeConsumer<T>(function);
-    }
-
-    private static class ThreadSafeConsumer<T>
-              extends WrappedFunction<Consumer<T>> implements Consumer<T> {
-        private static final long serialVersionUID = 1L;
-
-        ThreadSafeConsumer(Consumer<T> function) {
-            super(function);
-        }
-
-        @Override
-        public void accept(T value) {
-            final Consumer<T> function = f();
-            synchronized (function) {
-                function.accept(value);
-            }
-        }       
-    }
-    
-    /**
-     * Return a thread-safe version of a {@code BiFunction} function.
-     * If the function is guaranteed to be immutable (stateless)
-     * then the function is returned, as it is thread safe,
-     * otherwise a wrapper is returned that grabs synchronization
-     * on {@code function} when calling {@link BiFunction#apply(Object, Object)}.
-     * <BR>
-     * If {@code function} implements {@code AutoCloseable} then
-     * the function is assumed to be stateful and a thread-safe
-     * version is returned.
-     * @param <T> Type of function's first argument
-     * @param <U> Type of function's second argument
-     * @param <R> Type of function's third argument
-     * @param function Function to return a thread-safe version of.
-     * @return A thread-safe function
-     */
-    public static <T,U,R> BiFunction<T,U,R> synchronizedBiFunction(final BiFunction<T,U,R> function) {
-        if (isImmutable(function) && !(function instanceof AutoCloseable))
-            return function;
-        
-        // Return a function that is synchronized on the passed in function reference.
-        return new ThreadSafeBiFunction<T,U,R>(function);
-    }
-
-    private static class ThreadSafeBiFunction<T,U,R>
-              extends WrappedFunction<BiFunction<T,U,R>> implements BiFunction<T,U,R> {
-        private static final long serialVersionUID = 1L;
-
-        ThreadSafeBiFunction(BiFunction<T,U,R> function) {
-            super(function);
-        }
-
-        @Override
-        public R apply(T t, U u) {
-            final BiFunction<T,U,R> function = f();
-            synchronized (function) {
-                return function.apply(t, u);
-            }
-        }       
-    }
-    
-    /**
-     * See if the functional logic is immutable.
-     * 
-     * Logic is stateful if:
-     *   Has a non-final instance field.
-     *   Has a final instance field that is not a primitive
-     *   or a known immutable object.
-     *   
-     * @param function Function to check
-     * @return True if the function is immutable..
-     */
-    public static boolean isImmutable(Object function) {
-        return isImmutableClass(function.getClass());
-    }
-    
-    /**
-     * See if a function class is immutable.
-     * 
-     * Logic is stateful if:
-     *   Has a non-final instance field.
-     *   Has a final instance field that is not a primitive
-     *   or a known immutable object.
-     *   
-     * @param clazz Class to check
-     * @return True if the function is immutable..
-     */
-    public static boolean isImmutableClass(Class<?> clazz) {
-               
-        do {
-               Field[] fields = clazz.getDeclaredFields();
-               for (Field field : fields) {
-                   if (Modifier.isStatic(field.getModifiers()))
-                       continue;
-                   
-                   if (Modifier.isTransient(field.getModifiers()))
-                       continue;
-                   
-                   if (!Modifier.isFinal(field.getModifiers()))
-                       return false;
-                   
-                   if (field.getType().isPrimitive())
-                       continue; 
-                   
-                   if (immutableClasses.contains(field.getType()))
-                       continue;
-                   
-                   if (field.getType().isEnum()) {
-                       if (isImmutable(field.getType()))
-                           continue;
-                   }
-                   
-                   return false;
-               }
-               
-               clazz = clazz.getSuperclass();
-               
-        } while (!Object.class.equals(clazz));
-        
-        return true;
-    }
-    
-    private static final Set<Class<?>> immutableClasses = new HashSet<>();
-    static {
-        immutableClasses.add(String.class);
-        
-        immutableClasses.add(Boolean.class);
-        
-        immutableClasses.add(Byte.class);
-        immutableClasses.add(Short.class);
-        immutableClasses.add(Integer.class);
-        immutableClasses.add(Long.class);
-        
-        immutableClasses.add(BigInteger.class);
-        immutableClasses.add(BigDecimal.class);
-        
-        immutableClasses.add(Float.class);
-        immutableClasses.add(Double.class);
-        
-        immutableClasses.add(File.class);
-        
-        immutableClasses.add(Character.class);
-        
-        immutableClasses.add(Locale.class);
-        immutableClasses.add(UUID.class);
-        
-    }
-    
-    /**
-     * Create a {@code Runnable} that calls
-     * {@code consumer.accept(value)} when {@code run()} is called.
-     * This can be used to delay the execution of the consumer
-     * until some time in the future using an executor service.
-     * 
-     * @param <T> tuple type
-     * @param consumer Function to be applied to {@code value}.
-     * @param value Value to be consumed.
-     * 
-     * @return {@code Runnable} that invokes {@code consumer.accept(value)}.
-     */
-    public static <T> Runnable delayedConsume(Consumer<T> consumer, T value) {
-        return () -> consumer.accept(value);
-    }
-    
-    /**
-     * Wrap a {@code Runnable} with a final action that
-     * is always called when {@code action.run()} completes.
-     * @param action Action to be invoked before {@code finalAction}.
-     * @param finalAction Action to be invoked after {@code action.run()} is called.
-     * @return {@code Runnable} that invokes {@code action.run()} and then {@code finalAction.run()}
-     */
-    public static Runnable runWithFinal(Runnable action, Runnable finalAction) {
-        return () -> { try {action.run(); } finally {finalAction.run();}};
-    }
-
-    /**
-     * A Consumer that discards all items passed to it.
-     */
-    private static final Consumer<Object> DISCARDER = t -> {};
-
-
-    /**
-     * A Consumer that discards all items passed to it.
-     * @param <T> tuple type
-     * @return A Consumer that discards all items passed to it.
-     */
-    @SuppressWarnings("unchecked")
-    public static <T> Consumer<T> discard() {
-        return (Consumer<T>) DISCARDER;
-    }
-    
-    /**
-     * A Predicate that is always true.
-     */
-    private static final Predicate<Object> TRUE = t -> true;
-    
-    /**
-     * A Predicate that is always false.
-     */
-    private static final Predicate<Object> FALSE = t -> false;
-    
-    /**
-     * A Predicate that is always true
-     * @param <T> tuple type
-     * @return A Predicate that is always true.
-     */
-    @SuppressWarnings("unchecked")
-    public static <T> Predicate<T> alwaysTrue() {
-        return (Predicate<T>) TRUE;
-    }
-    
-    /**
-     * A Predicate that is always false
-     * @param <T> tuple type
-     * @return A Predicate that is always false.
-     */
-    @SuppressWarnings("unchecked")
-    public static <T> Predicate<T> alwaysFalse() {
-        return (Predicate<T>) FALSE;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-quarks/blob/a129aa16/api/function/src/main/java/edgent/function/Predicate.java
----------------------------------------------------------------------
diff --git a/api/function/src/main/java/edgent/function/Predicate.java b/api/function/src/main/java/edgent/function/Predicate.java
deleted file mode 100644
index 6a3afb6..0000000
--- a/api/function/src/main/java/edgent/function/Predicate.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
-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 edgent.function;
-
-import java.io.Serializable;
-
-/**
- * Predicate function.
- *
- * @param <T> Type of value to be tested.
- */
-public interface Predicate<T> extends Serializable {
-    
-    /**
-     * Test a value against a predicate.
-     * @param value Value to be tested.
-     * @return True if this predicate is true for {@code value} otherwise false.
-     */
-    boolean test(T value);
-}

http://git-wip-us.apache.org/repos/asf/incubator-quarks/blob/a129aa16/api/function/src/main/java/edgent/function/Supplier.java
----------------------------------------------------------------------
diff --git a/api/function/src/main/java/edgent/function/Supplier.java b/api/function/src/main/java/edgent/function/Supplier.java
deleted file mode 100644
index e00f546..0000000
--- a/api/function/src/main/java/edgent/function/Supplier.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
-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 edgent.function;
-
-import java.io.Serializable;
-
-/**
- * Function that supplies a value.
- * For example, functions that returns the current time:
- * <UL>
- * <LI>
- * As a lambda expression {@code () -> System.currentTimeMillis()}
- * </LI>
- * <LI>
- * As a method reference {@code () -> System::currentTimeMillis}
- * </LI>
- * </UL>
- *
- * @param <T> Type of function return.
- */
-public interface Supplier<T> extends Serializable {
-    /**
-     * Supply a value, each call to this function may return
-     * a different value.
-     * @return Value supplied by this function.
-     */
-    T get();
-}

http://git-wip-us.apache.org/repos/asf/incubator-quarks/blob/a129aa16/api/function/src/main/java/edgent/function/ToDoubleFunction.java
----------------------------------------------------------------------
diff --git a/api/function/src/main/java/edgent/function/ToDoubleFunction.java b/api/function/src/main/java/edgent/function/ToDoubleFunction.java
deleted file mode 100644
index aded056..0000000
--- a/api/function/src/main/java/edgent/function/ToDoubleFunction.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
-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 edgent.function;
-
-/**
- * Function that returns a double primitive.
- *
- * @param <T> Type of function argument.
- */
-public interface ToDoubleFunction<T> {
-    /**
-     * Apply a function to {@code value}.
-     * @param value Value the function is applied to
-     * @return Result of the function against {@code value}.
-     */
-    double applyAsDouble(T value);
-}

http://git-wip-us.apache.org/repos/asf/incubator-quarks/blob/a129aa16/api/function/src/main/java/edgent/function/ToIntFunction.java
----------------------------------------------------------------------
diff --git a/api/function/src/main/java/edgent/function/ToIntFunction.java b/api/function/src/main/java/edgent/function/ToIntFunction.java
deleted file mode 100644
index ae839b3..0000000
--- a/api/function/src/main/java/edgent/function/ToIntFunction.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
-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 edgent.function;
-
-import java.io.Serializable;
-
-/**
- * Function that returns a int primitive.
- *
- * @param <T> Type of function argument.
- */
-public interface ToIntFunction<T> extends Serializable {
-    /**
-     * Apply a function to {@code value}.
-     * @param value Value the function is applied to
-     * @return Result of the function against {@code value}.
-     */
-    int applyAsInt(T value);
-}

http://git-wip-us.apache.org/repos/asf/incubator-quarks/blob/a129aa16/api/function/src/main/java/edgent/function/UnaryOperator.java
----------------------------------------------------------------------
diff --git a/api/function/src/main/java/edgent/function/UnaryOperator.java b/api/function/src/main/java/edgent/function/UnaryOperator.java
deleted file mode 100644
index 5f4b55e..0000000
--- a/api/function/src/main/java/edgent/function/UnaryOperator.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
-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 edgent.function;
-
-/**
- * Function that returns the same type as its argument.
- *
- * @param <T> Type of function argument and return.
- */
-public interface UnaryOperator<T> extends Function<T, T> {
-}

http://git-wip-us.apache.org/repos/asf/incubator-quarks/blob/a129aa16/api/function/src/main/java/edgent/function/WrappedFunction.java
----------------------------------------------------------------------
diff --git a/api/function/src/main/java/edgent/function/WrappedFunction.java b/api/function/src/main/java/edgent/function/WrappedFunction.java
deleted file mode 100644
index d87ec94..0000000
--- a/api/function/src/main/java/edgent/function/WrappedFunction.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
-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 edgent.function;
-
-import java.io.Serializable;
-
-/**
- * A wrapped function. 
- *
- * @param <F> Type of function being wrapped.
- */
-public abstract class WrappedFunction<F> implements Serializable {
-    private static final long serialVersionUID = 1L;
-    
-    private final F f;
-    
-    protected WrappedFunction(F f) {
-        this.f = f;
-    }
-    
-    /**
-     * Function that was wrapped.
-     * @return Function that was wrapped.
-     */
-    public final F f() { return f; }
-    
-    /**
-     * Unwrap to find the outermost function that is an instance of {@code clazz}.
-     * @param <C> Type of class.
-     * @param clazz Implementation class to search for.
-     * @return outermost function that is an instance of {@code clazz},
-     * {@code null} if {@code clazz} is not implemented by {@code this}
-     * or any function it wraps.
-     * 
-     * @see WrappedFunction#unwrap(Class, Object)
-     */
-    public <C> C unwrap(Class<C> clazz) {
-        return unwrap(clazz, this);
-    }
-    
-    /**
-     * Unwrap a function object to find the outermost function that implements {@code clazz}.
-     * If a function object is not an instance of {@code clazz} but is an instance of
-     * {@code WrappedFunction} then the test is repeated on the value of {@link #f()}.
-     *  
-     * @param <C> Type of class.
-     * @param clazz Implementation class to search for.
-     * @param wf Function to unwrap
-     * @return outermost function that implements {@code clazz}, {@code null} if
-     * if {@code clazz} is not implemented by {@code wf} or any function it wraps.
-     */
-    public static <C> C unwrap(Class<C> clazz, Object wf) {
-        
-        for (;;) {
-            if (clazz.isInstance(wf))
-                return clazz.cast(wf);
-            if (wf instanceof WrappedFunction)
-                wf = ((WrappedFunction<?>) wf).f();
-            else
-                return null;              
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-quarks/blob/a129aa16/api/function/src/main/java/edgent/function/package-info.java
----------------------------------------------------------------------
diff --git a/api/function/src/main/java/edgent/function/package-info.java b/api/function/src/main/java/edgent/function/package-info.java
deleted file mode 100644
index 104309e..0000000
--- a/api/function/src/main/java/edgent/function/package-info.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
-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.
-*/
-
-/**
- * Functional interfaces for lambda expressions.
- */
-package edgent.function;
-

http://git-wip-us.apache.org/repos/asf/incubator-quarks/blob/a129aa16/api/function/src/main/java/org/apache/edgent/function/BiConsumer.java
----------------------------------------------------------------------
diff --git a/api/function/src/main/java/org/apache/edgent/function/BiConsumer.java b/api/function/src/main/java/org/apache/edgent/function/BiConsumer.java
new file mode 100644
index 0000000..2d4c112
--- /dev/null
+++ b/api/function/src/main/java/org/apache/edgent/function/BiConsumer.java
@@ -0,0 +1,36 @@
+/*
+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 org.apache.edgent.function;
+
+import java.io.Serializable;
+
+/**
+ * Consumer function that takes two arguments.
+ * @param <T> Type of the first function argument
+ * @param <U> Type of the second function argument
+ */
+public interface BiConsumer<T,U> extends Serializable {
+    
+    /**
+     * Consume the two arguments.
+     * @param t First function argument
+     * @param u Second function argument
+     */
+    void accept(T t, U u);
+}

http://git-wip-us.apache.org/repos/asf/incubator-quarks/blob/a129aa16/api/function/src/main/java/org/apache/edgent/function/BiFunction.java
----------------------------------------------------------------------
diff --git a/api/function/src/main/java/org/apache/edgent/function/BiFunction.java b/api/function/src/main/java/org/apache/edgent/function/BiFunction.java
new file mode 100644
index 0000000..048f294
--- /dev/null
+++ b/api/function/src/main/java/org/apache/edgent/function/BiFunction.java
@@ -0,0 +1,39 @@
+/*
+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 org.apache.edgent.function;
+
+import java.io.Serializable;
+
+/**
+ * Function that takes two arguments and returns a value.
+ *
+ * @param <T> Type of function's first argument
+ * @param <U> Type of function's second argument
+ * @param <R> Type of function return.
+ */
+public interface BiFunction<T, U, R> extends Serializable {
+    
+    /**
+     * Apply a function to {@code t} and {@code u}.
+     * @param t First argument the function is applied to.
+     * @param u Second argument the function is applied to.
+     * @return Result of the function against {@code t} and {@code u}.
+     */
+    R apply(T t, U u);
+}

http://git-wip-us.apache.org/repos/asf/incubator-quarks/blob/a129aa16/api/function/src/main/java/org/apache/edgent/function/Consumer.java
----------------------------------------------------------------------
diff --git a/api/function/src/main/java/org/apache/edgent/function/Consumer.java b/api/function/src/main/java/org/apache/edgent/function/Consumer.java
new file mode 100644
index 0000000..1f86282
--- /dev/null
+++ b/api/function/src/main/java/org/apache/edgent/function/Consumer.java
@@ -0,0 +1,35 @@
+/*
+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 org.apache.edgent.function;
+
+import java.io.Serializable;
+
+/**
+ * Function that consumes a value.
+ *
+ * @param <T> Type of function argument.
+ */
+public interface Consumer<T> extends Serializable {
+    
+    /**
+     * Apply the function to {@code value}.
+     * @param value Value function is applied to.
+     */
+    void accept(T value);
+}

http://git-wip-us.apache.org/repos/asf/incubator-quarks/blob/a129aa16/api/function/src/main/java/org/apache/edgent/function/Function.java
----------------------------------------------------------------------
diff --git a/api/function/src/main/java/org/apache/edgent/function/Function.java b/api/function/src/main/java/org/apache/edgent/function/Function.java
new file mode 100644
index 0000000..0887793
--- /dev/null
+++ b/api/function/src/main/java/org/apache/edgent/function/Function.java
@@ -0,0 +1,46 @@
+/*
+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 org.apache.edgent.function;
+
+import java.io.Serializable;
+
+/**
+ * Single argument function.
+ * For example:
+ * <UL>
+ * <LI>
+ * A function that doubles a value {@code v -> v * 2}
+ * </LI>
+ * <LI>
+ * A function that trims a {@code String} {@code v -> v.trim()} or {@code v -> String::trim}
+ * </LI>
+ * </UL>
+ *
+ * @param <T> Type of function argument.
+ * @param <R> Type of function return.
+ */
+public interface Function<T, R> extends Serializable {
+    
+    /**
+     * Apply a function to {@code value}.
+     * @param value Value the function is applied to
+     * @return Result of the function against {@code value}.
+     */
+    R apply(T value);
+}

http://git-wip-us.apache.org/repos/asf/incubator-quarks/blob/a129aa16/api/function/src/main/java/org/apache/edgent/function/Functions.java
----------------------------------------------------------------------
diff --git a/api/function/src/main/java/org/apache/edgent/function/Functions.java b/api/function/src/main/java/org/apache/edgent/function/Functions.java
new file mode 100644
index 0000000..d41e37a
--- /dev/null
+++ b/api/function/src/main/java/org/apache/edgent/function/Functions.java
@@ -0,0 +1,409 @@
+/*
+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 org.apache.edgent.function;
+
+import java.io.File;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Set;
+import java.util.UUID;
+
+/**
+ * Common functions and functional utilities.
+ *
+ */
+public class Functions {
+    
+    /**
+     * Single instance of the identity function.
+     */
+    private static final UnaryOperator<Object> IDENTITY = t -> t;
+    
+    /**
+     * Single instance of constant function that returns zero.
+     */
+    private static final Function<Object,Integer> ZERO = t -> 0;
+
+    
+    /**
+     * Returns the identity function that returns its single argument.
+     * @param <T> tuple type
+     * @return Identity function that returns its single argument.
+     */
+    @SuppressWarnings("unchecked")
+    public static <T> UnaryOperator<T> identity() {
+        return (UnaryOperator<T>) IDENTITY;
+    }
+    
+    /**
+     * Returns a constant function that returns zero (0).
+     * @param <T> tuple type
+     * @return Constant function that returns zero (0).
+     */
+    @SuppressWarnings("unchecked")
+    public static <T> Function<T,Integer> zero() {
+        return (Function<T, Integer>) ZERO;
+    }
+    
+    /**
+     * Returns a constant function that returns zero (0).
+     * This is identical to {@link #zero()} but is more
+     * readable when applied as a key function.
+     * @param <T> tuple type
+     * @return Constant function that returns zero (0).
+     */
+    public static <T> Function<T,Integer> unpartitioned() {
+        return zero();
+    }
+    
+    /**
+     * Close the function.
+     * If {@code function} is an instance of {@code AutoCloseable}
+     * then close is called, otherwise no action is taken.
+     * @param function Function to be closed.
+     * @throws Exception Error throwing function.
+     */
+    public static void closeFunction(Object function) throws Exception {
+        
+        AutoCloseable closeable = WrappedFunction.unwrap(AutoCloseable.class, function);
+        if (closeable != null)
+            closeable.close();
+    }
+    
+    /**
+     * Return a thread-safe version of a {@code Function} function.
+     * If the function is guaranteed to be immutable (stateless)
+     * then the function is returned, as it is thread safe,
+     * otherwise a wrapper is returned that grabs synchronization
+     * on {@code function} when calling {@link Function#apply(Object)}.
+     * <BR>
+     * If {@code function} implements {@code AutoCloseable} then
+     * the function is assumed to be stateful and a thread-safe
+     * version is returned.
+     * @param <T> source tuple type
+     * @param <R> result tuple type
+     * @param function Function to return a thread-safe version of.
+     * @return A thread-safe function
+     */
+    public static <T,R> Function<T,R> synchronizedFunction(final Function<T,R> function) {
+        if (isImmutable(function) && !(function instanceof AutoCloseable))
+            return function;
+        
+        // Return a function that is synchronized on the passed in function reference.
+        return new ThreadSafeFunction<T,R>(function);
+    }
+    
+    private static class ThreadSafeFunction<T,R> extends WrappedFunction<Function<T,R>> implements Function<T,R> {
+        private static final long serialVersionUID = 1L;
+
+        ThreadSafeFunction(Function<T,R> function) {
+            super(function);
+        }
+
+        @Override
+        public R apply(T value) {
+            final Function<T,R> function = f();
+            synchronized (function) {
+                return function.apply(value);
+            }
+        }
+    }
+    
+    /**
+     * Return a thread-safe version of a {@code Supplier} function.
+     * If the function is guaranteed to be immutable (stateless)
+     * then the function is returned, as it is thread safe,
+     * otherwise a wrapper is returned that grabs synchronization
+     * on {@code function} when calling {@link Supplier#get()}.
+     * <BR>
+     * If {@code function} implements {@code AutoCloseable} then
+     * the function is assumed to be stateful and a thread-safe
+     * version is returned.
+     * @param <T> tuple type
+     * @param function Function to return a thread-safe version of.
+     * @return A thread-safe function
+     */
+    public static <T> Supplier<T> synchronizedSupplier(final Supplier<T> function) {
+        if (isImmutable(function) && !(function instanceof AutoCloseable))
+            return function;
+        
+        // Return a function that is synchronized on the passed in function reference.
+        return new ThreadSafeSupplier<T>(function);
+    }
+
+    private static class ThreadSafeSupplier<T> extends WrappedFunction<Supplier<T>> implements Supplier<T> {
+        private static final long serialVersionUID = 1L;
+
+        ThreadSafeSupplier(Supplier<T> function) {
+            super(function);
+        }
+
+        @Override
+        public T get() {
+            final Supplier<T> function = f();
+            synchronized (function) {
+                return function.get();
+            }
+        }
+    }
+    
+    /**
+     * Return a thread-safe version of a {@code Consumer} function.
+     * If the function is guaranteed to be immutable (stateless)
+     * then the function is returned, as it is thread safe,
+     * otherwise a wrapper is returned that grabs synchronization
+     * on {@code function} when calling {@link Consumer#accept(Object)}.
+     * <BR>
+     * If {@code function} implements {@code AutoCloseable} then
+     * the function is assumed to be stateful and a thread-safe
+     * version is returned.
+     * @param <T> tuple type
+     * @param function Function to return a thread-safe version of.
+     * @return A thread-safe function
+     */
+    public static <T> Consumer<T> synchronizedConsumer(final Consumer<T> function) {
+        if (isImmutable(function) && !(function instanceof AutoCloseable))
+            return function;
+        
+        // Return a function that is synchronized on the passed in function reference.
+        return new ThreadSafeConsumer<T>(function);
+    }
+
+    private static class ThreadSafeConsumer<T>
+              extends WrappedFunction<Consumer<T>> implements Consumer<T> {
+        private static final long serialVersionUID = 1L;
+
+        ThreadSafeConsumer(Consumer<T> function) {
+            super(function);
+        }
+
+        @Override
+        public void accept(T value) {
+            final Consumer<T> function = f();
+            synchronized (function) {
+                function.accept(value);
+            }
+        }       
+    }
+    
+    /**
+     * Return a thread-safe version of a {@code BiFunction} function.
+     * If the function is guaranteed to be immutable (stateless)
+     * then the function is returned, as it is thread safe,
+     * otherwise a wrapper is returned that grabs synchronization
+     * on {@code function} when calling {@link BiFunction#apply(Object, Object)}.
+     * <BR>
+     * If {@code function} implements {@code AutoCloseable} then
+     * the function is assumed to be stateful and a thread-safe
+     * version is returned.
+     * @param <T> Type of function's first argument
+     * @param <U> Type of function's second argument
+     * @param <R> Type of function's third argument
+     * @param function Function to return a thread-safe version of.
+     * @return A thread-safe function
+     */
+    public static <T,U,R> BiFunction<T,U,R> synchronizedBiFunction(final BiFunction<T,U,R> function) {
+        if (isImmutable(function) && !(function instanceof AutoCloseable))
+            return function;
+        
+        // Return a function that is synchronized on the passed in function reference.
+        return new ThreadSafeBiFunction<T,U,R>(function);
+    }
+
+    private static class ThreadSafeBiFunction<T,U,R>
+              extends WrappedFunction<BiFunction<T,U,R>> implements BiFunction<T,U,R> {
+        private static final long serialVersionUID = 1L;
+
+        ThreadSafeBiFunction(BiFunction<T,U,R> function) {
+            super(function);
+        }
+
+        @Override
+        public R apply(T t, U u) {
+            final BiFunction<T,U,R> function = f();
+            synchronized (function) {
+                return function.apply(t, u);
+            }
+        }       
+    }
+    
+    /**
+     * See if the functional logic is immutable.
+     * 
+     * Logic is stateful if:
+     *   Has a non-final instance field.
+     *   Has a final instance field that is not a primitive
+     *   or a known immutable object.
+     *   
+     * @param function Function to check
+     * @return True if the function is immutable..
+     */
+    public static boolean isImmutable(Object function) {
+        return isImmutableClass(function.getClass());
+    }
+    
+    /**
+     * See if a function class is immutable.
+     * 
+     * Logic is stateful if:
+     *   Has a non-final instance field.
+     *   Has a final instance field that is not a primitive
+     *   or a known immutable object.
+     *   
+     * @param clazz Class to check
+     * @return True if the function is immutable..
+     */
+    public static boolean isImmutableClass(Class<?> clazz) {
+               
+        do {
+               Field[] fields = clazz.getDeclaredFields();
+               for (Field field : fields) {
+                   if (Modifier.isStatic(field.getModifiers()))
+                       continue;
+                   
+                   if (Modifier.isTransient(field.getModifiers()))
+                       continue;
+                   
+                   if (!Modifier.isFinal(field.getModifiers()))
+                       return false;
+                   
+                   if (field.getType().isPrimitive())
+                       continue; 
+                   
+                   if (immutableClasses.contains(field.getType()))
+                       continue;
+                   
+                   if (field.getType().isEnum()) {
+                       if (isImmutable(field.getType()))
+                           continue;
+                   }
+                   
+                   return false;
+               }
+               
+               clazz = clazz.getSuperclass();
+               
+        } while (!Object.class.equals(clazz));
+        
+        return true;
+    }
+    
+    private static final Set<Class<?>> immutableClasses = new HashSet<>();
+    static {
+        immutableClasses.add(String.class);
+        
+        immutableClasses.add(Boolean.class);
+        
+        immutableClasses.add(Byte.class);
+        immutableClasses.add(Short.class);
+        immutableClasses.add(Integer.class);
+        immutableClasses.add(Long.class);
+        
+        immutableClasses.add(BigInteger.class);
+        immutableClasses.add(BigDecimal.class);
+        
+        immutableClasses.add(Float.class);
+        immutableClasses.add(Double.class);
+        
+        immutableClasses.add(File.class);
+        
+        immutableClasses.add(Character.class);
+        
+        immutableClasses.add(Locale.class);
+        immutableClasses.add(UUID.class);
+        
+    }
+    
+    /**
+     * Create a {@code Runnable} that calls
+     * {@code consumer.accept(value)} when {@code run()} is called.
+     * This can be used to delay the execution of the consumer
+     * until some time in the future using an executor service.
+     * 
+     * @param <T> tuple type
+     * @param consumer Function to be applied to {@code value}.
+     * @param value Value to be consumed.
+     * 
+     * @return {@code Runnable} that invokes {@code consumer.accept(value)}.
+     */
+    public static <T> Runnable delayedConsume(Consumer<T> consumer, T value) {
+        return () -> consumer.accept(value);
+    }
+    
+    /**
+     * Wrap a {@code Runnable} with a final action that
+     * is always called when {@code action.run()} completes.
+     * @param action Action to be invoked before {@code finalAction}.
+     * @param finalAction Action to be invoked after {@code action.run()} is called.
+     * @return {@code Runnable} that invokes {@code action.run()} and then {@code finalAction.run()}
+     */
+    public static Runnable runWithFinal(Runnable action, Runnable finalAction) {
+        return () -> { try {action.run(); } finally {finalAction.run();}};
+    }
+
+    /**
+     * A Consumer that discards all items passed to it.
+     */
+    private static final Consumer<Object> DISCARDER = t -> {};
+
+
+    /**
+     * A Consumer that discards all items passed to it.
+     * @param <T> tuple type
+     * @return A Consumer that discards all items passed to it.
+     */
+    @SuppressWarnings("unchecked")
+    public static <T> Consumer<T> discard() {
+        return (Consumer<T>) DISCARDER;
+    }
+    
+    /**
+     * A Predicate that is always true.
+     */
+    private static final Predicate<Object> TRUE = t -> true;
+    
+    /**
+     * A Predicate that is always false.
+     */
+    private static final Predicate<Object> FALSE = t -> false;
+    
+    /**
+     * A Predicate that is always true
+     * @param <T> tuple type
+     * @return A Predicate that is always true.
+     */
+    @SuppressWarnings("unchecked")
+    public static <T> Predicate<T> alwaysTrue() {
+        return (Predicate<T>) TRUE;
+    }
+    
+    /**
+     * A Predicate that is always false
+     * @param <T> tuple type
+     * @return A Predicate that is always false.
+     */
+    @SuppressWarnings("unchecked")
+    public static <T> Predicate<T> alwaysFalse() {
+        return (Predicate<T>) FALSE;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-quarks/blob/a129aa16/api/function/src/main/java/org/apache/edgent/function/Predicate.java
----------------------------------------------------------------------
diff --git a/api/function/src/main/java/org/apache/edgent/function/Predicate.java b/api/function/src/main/java/org/apache/edgent/function/Predicate.java
new file mode 100644
index 0000000..6c51909
--- /dev/null
+++ b/api/function/src/main/java/org/apache/edgent/function/Predicate.java
@@ -0,0 +1,36 @@
+/*
+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 org.apache.edgent.function;
+
+import java.io.Serializable;
+
+/**
+ * Predicate function.
+ *
+ * @param <T> Type of value to be tested.
+ */
+public interface Predicate<T> extends Serializable {
+    
+    /**
+     * Test a value against a predicate.
+     * @param value Value to be tested.
+     * @return True if this predicate is true for {@code value} otherwise false.
+     */
+    boolean test(T value);
+}

http://git-wip-us.apache.org/repos/asf/incubator-quarks/blob/a129aa16/api/function/src/main/java/org/apache/edgent/function/Supplier.java
----------------------------------------------------------------------
diff --git a/api/function/src/main/java/org/apache/edgent/function/Supplier.java b/api/function/src/main/java/org/apache/edgent/function/Supplier.java
new file mode 100644
index 0000000..1e45240
--- /dev/null
+++ b/api/function/src/main/java/org/apache/edgent/function/Supplier.java
@@ -0,0 +1,44 @@
+/*
+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 org.apache.edgent.function;
+
+import java.io.Serializable;
+
+/**
+ * Function that supplies a value.
+ * For example, functions that returns the current time:
+ * <UL>
+ * <LI>
+ * As a lambda expression {@code () -> System.currentTimeMillis()}
+ * </LI>
+ * <LI>
+ * As a method reference {@code () -> System::currentTimeMillis}
+ * </LI>
+ * </UL>
+ *
+ * @param <T> Type of function return.
+ */
+public interface Supplier<T> extends Serializable {
+    /**
+     * Supply a value, each call to this function may return
+     * a different value.
+     * @return Value supplied by this function.
+     */
+    T get();
+}

http://git-wip-us.apache.org/repos/asf/incubator-quarks/blob/a129aa16/api/function/src/main/java/org/apache/edgent/function/ToDoubleFunction.java
----------------------------------------------------------------------
diff --git a/api/function/src/main/java/org/apache/edgent/function/ToDoubleFunction.java b/api/function/src/main/java/org/apache/edgent/function/ToDoubleFunction.java
new file mode 100644
index 0000000..c0ea61a
--- /dev/null
+++ b/api/function/src/main/java/org/apache/edgent/function/ToDoubleFunction.java
@@ -0,0 +1,33 @@
+/*
+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 org.apache.edgent.function;
+
+/**
+ * Function that returns a double primitive.
+ *
+ * @param <T> Type of function argument.
+ */
+public interface ToDoubleFunction<T> {
+    /**
+     * Apply a function to {@code value}.
+     * @param value Value the function is applied to
+     * @return Result of the function against {@code value}.
+     */
+    double applyAsDouble(T value);
+}

http://git-wip-us.apache.org/repos/asf/incubator-quarks/blob/a129aa16/api/function/src/main/java/org/apache/edgent/function/ToIntFunction.java
----------------------------------------------------------------------
diff --git a/api/function/src/main/java/org/apache/edgent/function/ToIntFunction.java b/api/function/src/main/java/org/apache/edgent/function/ToIntFunction.java
new file mode 100644
index 0000000..f4522b0
--- /dev/null
+++ b/api/function/src/main/java/org/apache/edgent/function/ToIntFunction.java
@@ -0,0 +1,35 @@
+/*
+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 org.apache.edgent.function;
+
+import java.io.Serializable;
+
+/**
+ * Function that returns a int primitive.
+ *
+ * @param <T> Type of function argument.
+ */
+public interface ToIntFunction<T> extends Serializable {
+    /**
+     * Apply a function to {@code value}.
+     * @param value Value the function is applied to
+     * @return Result of the function against {@code value}.
+     */
+    int applyAsInt(T value);
+}

http://git-wip-us.apache.org/repos/asf/incubator-quarks/blob/a129aa16/api/function/src/main/java/org/apache/edgent/function/UnaryOperator.java
----------------------------------------------------------------------
diff --git a/api/function/src/main/java/org/apache/edgent/function/UnaryOperator.java b/api/function/src/main/java/org/apache/edgent/function/UnaryOperator.java
new file mode 100644
index 0000000..c571a2f
--- /dev/null
+++ b/api/function/src/main/java/org/apache/edgent/function/UnaryOperator.java
@@ -0,0 +1,27 @@
+/*
+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 org.apache.edgent.function;
+
+/**
+ * Function that returns the same type as its argument.
+ *
+ * @param <T> Type of function argument and return.
+ */
+public interface UnaryOperator<T> extends Function<T, T> {
+}

http://git-wip-us.apache.org/repos/asf/incubator-quarks/blob/a129aa16/api/function/src/main/java/org/apache/edgent/function/WrappedFunction.java
----------------------------------------------------------------------
diff --git a/api/function/src/main/java/org/apache/edgent/function/WrappedFunction.java b/api/function/src/main/java/org/apache/edgent/function/WrappedFunction.java
new file mode 100644
index 0000000..5374b75
--- /dev/null
+++ b/api/function/src/main/java/org/apache/edgent/function/WrappedFunction.java
@@ -0,0 +1,79 @@
+/*
+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 org.apache.edgent.function;
+
+import java.io.Serializable;
+
+/**
+ * A wrapped function. 
+ *
+ * @param <F> Type of function being wrapped.
+ */
+public abstract class WrappedFunction<F> implements Serializable {
+    private static final long serialVersionUID = 1L;
+    
+    private final F f;
+    
+    protected WrappedFunction(F f) {
+        this.f = f;
+    }
+    
+    /**
+     * Function that was wrapped.
+     * @return Function that was wrapped.
+     */
+    public final F f() { return f; }
+    
+    /**
+     * Unwrap to find the outermost function that is an instance of {@code clazz}.
+     * @param <C> Type of class.
+     * @param clazz Implementation class to search for.
+     * @return outermost function that is an instance of {@code clazz},
+     * {@code null} if {@code clazz} is not implemented by {@code this}
+     * or any function it wraps.
+     * 
+     * @see WrappedFunction#unwrap(Class, Object)
+     */
+    public <C> C unwrap(Class<C> clazz) {
+        return unwrap(clazz, this);
+    }
+    
+    /**
+     * Unwrap a function object to find the outermost function that implements {@code clazz}.
+     * If a function object is not an instance of {@code clazz} but is an instance of
+     * {@code WrappedFunction} then the test is repeated on the value of {@link #f()}.
+     *  
+     * @param <C> Type of class.
+     * @param clazz Implementation class to search for.
+     * @param wf Function to unwrap
+     * @return outermost function that implements {@code clazz}, {@code null} if
+     * if {@code clazz} is not implemented by {@code wf} or any function it wraps.
+     */
+    public static <C> C unwrap(Class<C> clazz, Object wf) {
+        
+        for (;;) {
+            if (clazz.isInstance(wf))
+                return clazz.cast(wf);
+            if (wf instanceof WrappedFunction)
+                wf = ((WrappedFunction<?>) wf).f();
+            else
+                return null;              
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-quarks/blob/a129aa16/api/function/src/main/java/org/apache/edgent/function/package-info.java
----------------------------------------------------------------------
diff --git a/api/function/src/main/java/org/apache/edgent/function/package-info.java b/api/function/src/main/java/org/apache/edgent/function/package-info.java
new file mode 100644
index 0000000..ca37d22
--- /dev/null
+++ b/api/function/src/main/java/org/apache/edgent/function/package-info.java
@@ -0,0 +1,24 @@
+/*
+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.
+*/
+
+/**
+ * Functional interfaces for lambda expressions.
+ */
+package org.apache.edgent.function;
+