From 9bdba2b5de74b9cdb94b809bebbda7465243ecb9 Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Thu, 22 Sep 2016 22:06:04 +0000
Subject: [PATCH] OPENDJ-2877: declare RuntimeExceptions in Functions

---
 opendj-core/src/main/java/com/forgerock/opendj/util/Collections2.java                            |   49 ++++--
 opendj-core/src/main/java/com/forgerock/opendj/util/Iterables.java                               |   35 ++--
 opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/SimplePropertyMapper.java          |   13 -
 opendj-core/src/main/java/org/forgerock/opendj/ldap/Functions.java                               |  108 +++++++--------
 opendj-server-legacy/src/main/java/org/opends/server/protocols/http/rest2ldap/AdminEndpoint.java |    5 
 opendj-core/src/main/java/com/forgerock/opendj/util/Iterators.java                               |   15 +-
 opendj-core/src/main/java/org/forgerock/opendj/ldap/RootDSE.java                                 |   19 +-
 opendj-core/src/main/java/org/forgerock/opendj/ldap/AttributeParser.java                         |   98 +++++++------
 opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Utils.java                         |    2 
 opendj-server-legacy/src/main/java/org/opends/server/types/AttributeParser.java                  |   29 +++-
 10 files changed, 202 insertions(+), 171 deletions(-)

diff --git a/opendj-core/src/main/java/com/forgerock/opendj/util/Collections2.java b/opendj-core/src/main/java/com/forgerock/opendj/util/Collections2.java
index c5940e7..53d97ef 100644
--- a/opendj-core/src/main/java/com/forgerock/opendj/util/Collections2.java
+++ b/opendj-core/src/main/java/com/forgerock/opendj/util/Collections2.java
@@ -16,6 +16,8 @@
  */
 package com.forgerock.opendj.util;
 
+import static com.forgerock.opendj.util.Iterators.transformedIterator;
+
 import java.util.AbstractCollection;
 import java.util.Collection;
 import java.util.Iterator;
@@ -23,21 +25,20 @@
 import java.util.ListIterator;
 
 import org.forgerock.util.Function;
-import org.forgerock.util.promise.NeverThrowsException;
 
 /** Additional {@code Collection} based utility methods. */
 public final class Collections2 {
-    private static class TransformedCollection<M, N, C extends Collection<M>> extends
-            AbstractCollection<N> implements Collection<N> {
+    private static class TransformedCollection<M, N, C extends Collection<M>, E0 extends RuntimeException,
+            E1 extends RuntimeException> extends AbstractCollection<N> implements Collection<N> {
         protected final C collection;
 
-        protected final Function<? super M, ? extends N, NeverThrowsException> funcMtoN;
+        final Function<? super M, ? extends N, E0> funcMtoN;
 
-        protected final Function<? super N, ? extends M, NeverThrowsException> funcNtoM;
+        final Function<? super N, ? extends M, E1> funcNtoM;
 
-        protected TransformedCollection(final C collection,
-                final Function<? super M, ? extends N, NeverThrowsException> funcMtoN,
-                final Function<? super N, ? extends M, NeverThrowsException> funcNtoM) {
+        TransformedCollection(final C collection,
+                              final Function<? super M, ? extends N, E0> funcMtoN,
+                              final Function<? super N, ? extends M, E1> funcNtoM) {
             this.collection = collection;
             this.funcMtoN = funcMtoN;
             this.funcNtoM = funcNtoM;
@@ -66,7 +67,7 @@
 
         @Override
         public Iterator<N> iterator() {
-            return Iterators.transformedIterator(collection.iterator(), funcMtoN);
+            return transformedIterator(collection.iterator(), funcMtoN);
         }
 
         @Override
@@ -81,11 +82,11 @@
         }
     }
 
-    private static final class TransformedList<M, N> extends
-            TransformedCollection<M, N, List<M>> implements List<N> {
+    private static final class TransformedList<M, N, E0 extends RuntimeException, E1 extends RuntimeException>
+            extends TransformedCollection<M, N, List<M>, E0, E1> implements List<N> {
         private TransformedList(final List<M> list,
-                final Function<? super M, ? extends N, NeverThrowsException> funcMtoN,
-                final Function<? super N, ? extends M, NeverThrowsException> funcNtoM) {
+                                final Function<? super M, ? extends N, E0> funcMtoN,
+                                final Function<? super N, ? extends M, E1> funcNtoM) {
             super(list, funcMtoN, funcNtoM);
         }
 
@@ -206,6 +207,10 @@
      *            The type of elements contained in {@code collection}.
      * @param <N>
      *            The type of elements contained in the returned collection.
+     * @param <E0>
+     *            The type of exception thrown by {@code funcMtoN}.
+     * @param <E1>
+     *            The type of exception thrown by {@code funcNtoM}.
      * @param collection
      *            The collection to be transformed.
      * @param funcMtoN
@@ -219,9 +224,10 @@
      * @return A view of {@code collection} whose values have been mapped to
      *         elements of type {@code N} using {@code funcMtoN}.
      */
-    public static <M, N> Collection<N> transformedCollection(final Collection<M> collection,
-            final Function<? super M, ? extends N, NeverThrowsException> funcMtoN,
-            final Function<? super N, ? extends M, NeverThrowsException> funcNtoM) {
+    public static <M, N, E0 extends RuntimeException, E1 extends RuntimeException>
+    Collection<N> transformedCollection(final Collection<M> collection,
+                                        final Function<? super M, ? extends N, E0> funcMtoN,
+                                        final Function<? super N, ? extends M, E1> funcNtoM) {
         return new TransformedCollection<>(collection, funcMtoN, funcNtoM);
     }
 
@@ -234,6 +240,10 @@
      *            The type of elements contained in {@code list}.
      * @param <N>
      *            The type of elements contained in the returned list.
+     * @param <E0>
+     *            The type of exception thrown by {@code funcMtoN}.
+     * @param <E1>
+     *            The type of exception thrown by {@code funcNtoM}.
      * @param list
      *            The list to be transformed.
      * @param funcMtoN
@@ -247,9 +257,10 @@
      * @return A view of {@code list} whose values have been mapped to elements
      *         of type {@code N} using {@code funcMtoN}.
      */
-    public static <M, N> List<N> transformedList(final List<M> list,
-            final Function<? super M, ? extends N, NeverThrowsException> funcMtoN,
-            final Function<? super N, ? extends M, NeverThrowsException> funcNtoM) {
+    public static <M, N, E0 extends RuntimeException, E1 extends RuntimeException> List<N> transformedList(
+            final List<M> list,
+            final Function<? super M, ? extends N, E0> funcMtoN,
+            final Function<? super N, ? extends M, E1> funcNtoM) {
         return new TransformedList<>(list, funcMtoN, funcNtoM);
     }
 
diff --git a/opendj-core/src/main/java/com/forgerock/opendj/util/Iterables.java b/opendj-core/src/main/java/com/forgerock/opendj/util/Iterables.java
index 5b29ddc..5194c86 100644
--- a/opendj-core/src/main/java/com/forgerock/opendj/util/Iterables.java
+++ b/opendj-core/src/main/java/com/forgerock/opendj/util/Iterables.java
@@ -12,15 +12,16 @@
  * information: "Portions Copyright [year] [name of copyright owner]".
  *
  * Copyright 2009-2010 Sun Microsystems, Inc.
- * Portions copyright 2013-2015 ForgeRock AS.
+ * Portions copyright 2013-2016 ForgeRock AS.
  */
 package com.forgerock.opendj.util;
 
+import static com.forgerock.opendj.util.Iterators.*;
+
 import java.util.Collection;
 import java.util.Iterator;
 
 import org.forgerock.util.Function;
-import org.forgerock.util.promise.NeverThrowsException;
 
 /**
  * Utility methods for manipulating {@link Iterable}s.
@@ -43,14 +44,14 @@
 
         @Override
         public Iterator<M> iterator() {
-            return Iterators.arrayIterator(a);
+            return arrayIterator(a);
         }
     }
 
     private static final class EmptyIterable<M> extends AbstractIterable<M> {
         @Override
         public Iterator<M> iterator() {
-            return Iterators.emptyIterator();
+            return emptyIterator();
         }
     }
 
@@ -60,8 +61,7 @@
         private final Predicate<? super M, P> predicate;
 
         /** Constructed via factory methods. */
-        private FilteredIterable(final Iterable<M> iterable,
-                final Predicate<? super M, P> predicate, final P p) {
+        private FilteredIterable(final Iterable<M> iterable, final Predicate<? super M, P> predicate, final P p) {
             this.iterable = iterable;
             this.predicate = predicate;
             this.parameter = p;
@@ -69,7 +69,7 @@
 
         @Override
         public Iterator<M> iterator() {
-            return Iterators.filteredIterator(iterable.iterator(), predicate, parameter);
+            return filteredIterator(iterable.iterator(), predicate, parameter);
         }
     }
 
@@ -83,24 +83,23 @@
 
         @Override
         public Iterator<M> iterator() {
-            return Iterators.singletonIterator(value);
+            return singletonIterator(value);
         }
     }
 
-    private static final class TransformedIterable<M, N> extends AbstractIterable<N> {
-        private final Function<? super M, ? extends N, NeverThrowsException> function;
+    private static final class TransformedIterable<M, N, E extends RuntimeException> extends AbstractIterable<N> {
+        private final Function<? super M, ? extends N, E> function;
         private final Iterable<M> iterable;
 
         /** Constructed via factory methods. */
-        private TransformedIterable(final Iterable<M> iterable,
-                final Function<? super M, ? extends N, NeverThrowsException> function) {
+        private TransformedIterable(final Iterable<M> iterable, final Function<? super M, ? extends N, E> function) {
             this.iterable = iterable;
             this.function = function;
         }
 
         @Override
         public Iterator<N> iterator() {
-            return Iterators.transformedIterator(iterable.iterator(), function);
+            return transformedIterator(iterable.iterator(), function);
         }
     }
 
@@ -114,7 +113,7 @@
 
         @Override
         public Iterator<M> iterator() {
-            return Iterators.unmodifiableIterator(iterable.iterator());
+            return unmodifiableIterator(iterable.iterator());
         }
     }
 
@@ -261,7 +260,7 @@
     public static String toString(final Iterable<?> iterable) {
         if (iterable instanceof Collection) {
             // Fall-through if possible.
-            return ((Collection<?>) iterable).toString();
+            return iterable.toString();
         } else {
             final StringBuilder builder = new StringBuilder();
             boolean firstValue = true;
@@ -288,6 +287,8 @@
      *            The type of elements contained in {@code iterable}.
      * @param <N>
      *            The type of elements contained in the returned iterable.
+     * @param <E>
+     *            The type of the exception thrown by the function.
      * @param iterable
      *            The iterable to be transformed.
      * @param function
@@ -295,8 +296,8 @@
      * @return A view of {@code iterable} whose values have been mapped to
      *         elements of type {@code N} using {@code function}.
      */
-    public static <M, N> Iterable<N> transformedIterable(final Iterable<M> iterable,
-            final Function<? super M, ? extends N, NeverThrowsException> function) {
+    public static <M, N, E extends RuntimeException> Iterable<N> transformedIterable(
+            final Iterable<M> iterable, final Function<? super M, ? extends N, E> function) {
         return new TransformedIterable<>(iterable, function);
     }
 
diff --git a/opendj-core/src/main/java/com/forgerock/opendj/util/Iterators.java b/opendj-core/src/main/java/com/forgerock/opendj/util/Iterators.java
index bc5c51b..8f5152e 100644
--- a/opendj-core/src/main/java/com/forgerock/opendj/util/Iterators.java
+++ b/opendj-core/src/main/java/com/forgerock/opendj/util/Iterators.java
@@ -20,7 +20,6 @@
 import java.util.NoSuchElementException;
 
 import org.forgerock.util.Function;
-import org.forgerock.util.promise.NeverThrowsException;
 
 /** Utility methods for manipulating {@link Iterator}s. */
 public final class Iterators {
@@ -152,14 +151,12 @@
 
     }
 
-    private static final class TransformedIterator<M, N> implements Iterator<N> {
-
-        private final Function<? super M, ? extends N, NeverThrowsException> function;
+    private static final class TransformedIterator<M, N, E extends RuntimeException> implements Iterator<N> {
+        private final Function<? super M, ? extends N, E> function;
         private final Iterator<M> iterator;
 
         /** Constructed via factory methods. */
-        private TransformedIterator(final Iterator<M> iterator,
-                final Function<? super M, ? extends N, NeverThrowsException> function) {
+        private TransformedIterator(final Iterator<M> iterator, final Function<? super M, ? extends N, E> function) {
             this.iterator = iterator;
             this.function = function;
         }
@@ -304,6 +301,8 @@
      *            The type of elements contained in {@code iterator}.
      * @param <N>
      *            The type of elements contained in the returned iterator.
+     * @param <E>
+     *            The type of the exception thrown by the function.
      * @param iterator
      *            The iterator to be transformed.
      * @param function
@@ -311,8 +310,8 @@
      * @return A view of {@code iterator} whose values have been mapped to
      *         elements of type {@code N} using {@code function}.
      */
-    public static <M, N> Iterator<N> transformedIterator(final Iterator<M> iterator,
-            final Function<? super M, ? extends N, NeverThrowsException> function) {
+    public static <M, N, E extends RuntimeException> Iterator<N> transformedIterator(
+            final Iterator<M> iterator, final Function<? super M, ? extends N, E> function) {
         return new TransformedIterator<>(iterator, function);
     }
 
diff --git a/opendj-core/src/main/java/org/forgerock/opendj/ldap/AttributeParser.java b/opendj-core/src/main/java/org/forgerock/opendj/ldap/AttributeParser.java
index e65e5b4..a916433 100644
--- a/opendj-core/src/main/java/org/forgerock/opendj/ldap/AttributeParser.java
+++ b/opendj-core/src/main/java/org/forgerock/opendj/ldap/AttributeParser.java
@@ -11,22 +11,21 @@
  * Header, with the fields enclosed by brackets [] replaced by your own identifying
  * information: "Portions Copyright [year] [name of copyright owner]".
  *
- * Copyright 2012-2015 ForgeRock AS.
+ * Copyright 2012-2016 ForgeRock AS.
  */
 package org.forgerock.opendj.ldap;
 
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.LinkedHashSet;
-import java.util.NoSuchElementException;
 import java.util.Set;
 
 import org.forgerock.opendj.ldap.schema.Schema;
 import org.forgerock.util.Function;
-import org.forgerock.util.promise.NeverThrowsException;
 
 import static com.forgerock.opendj.util.Collections2.*;
+import static java.util.Arrays.asList;
+import static org.forgerock.opendj.ldap.Functions.*;
 
 /**
  * A fluent API for parsing attributes as different types of object. An
@@ -91,12 +90,16 @@
      * values.
      *
      * @param <T>
-     *            The type of the value to be decoded.
+     *         The type of the value to be decoded.
+     * @param <E>
+     *         The type of exception thrown by the function.
      * @param f
-     *            The function which should be used to decode the value.
+     *         The function which should be used to decode the value.
      * @return The first value decoded as a {@code T}.
+     * @throws E
+     *         If an error occurred when parsing the attribute.
      */
-    public <T> T as(final Function<ByteString, ? extends T, NeverThrowsException> f) {
+    public <T, E extends Exception> T as(final Function<ByteString, ? extends T, E> f) throws E {
         return as(f, null);
     }
 
@@ -107,13 +110,17 @@
      *
      * @param <T>
      *            The type of the value to be decoded.
+     * @param <E>
+     *            The type of exception thrown by the function.
      * @param f
      *            The function which should be used to decode the value.
      * @param defaultValue
      *            The default value to return if the attribute is empty.
      * @return The first value decoded as a {@code T}.
+     * @throws E
+     *         If an error occurred when parsing the attribute.
      */
-    public <T> T as(final Function<ByteString, ? extends T, NeverThrowsException> f, final T defaultValue) {
+    public <T, E extends Exception> T as(final Function<ByteString, ? extends T, E> f, final T defaultValue) throws E {
         if (!isEmpty(attribute)) {
             return f.apply(attribute.firstValue());
         } else {
@@ -142,7 +149,7 @@
      * @return The first value decoded as an {@code AttributeDescription}.
      */
     public AttributeDescription asAttributeDescription(final AttributeDescription defaultValue) {
-        return as(Functions.byteStringToAttributeDescription(getSchema()), defaultValue);
+        return as(byteStringToAttributeDescription(getSchema()), defaultValue);
     }
 
     /**
@@ -177,7 +184,7 @@
      * @return The first value decoded as an {@code Boolean}.
      */
     public boolean asBoolean(final boolean defaultValue) {
-        return as(Functions.byteStringToBoolean(), defaultValue);
+        return as(byteStringToBoolean(), defaultValue);
     }
 
     /**
@@ -223,7 +230,7 @@
      * @return The first value decoded as a {@code DN}.
      */
     public DN asDN(final DN defaultValue) {
-        return as(Functions.byteStringToDN(getSchema()), defaultValue);
+        return as(byteStringToDN(getSchema()), defaultValue);
     }
 
     /**
@@ -260,7 +267,7 @@
      * @return The first value decoded as an {@code GeneralizedTime}.
      */
     public GeneralizedTime asGeneralizedTime(final GeneralizedTime defaultValue) {
-        return as(Functions.byteStringToGeneralizedTime(), defaultValue);
+        return as(byteStringToGeneralizedTime(), defaultValue);
     }
 
     /**
@@ -282,7 +289,7 @@
      * @return The first value decoded as an {@code Integer}.
      */
     public int asInteger(final int defaultValue) {
-        return as(Functions.byteStringToInteger(), defaultValue);
+        return as(byteStringToInteger(), defaultValue);
     }
 
     /**
@@ -304,7 +311,7 @@
      * @return The first value decoded as a {@code Long}.
      */
     public long asLong(final long defaultValue) {
-        return as(Functions.byteStringToLong(), defaultValue);
+        return as(byteStringToLong(), defaultValue);
     }
 
     /**
@@ -314,14 +321,18 @@
      *
      * @param <T>
      *            The type of the values to be decoded.
+     * @param <E>
+     *            The type of exception thrown by the function.
      * @param f
      *            The function which should be used to decode values.
      * @param defaultValues
      *            The default values to return if the attribute is empty.
      * @return The values decoded as a set of {@code T}s.
+     * @throws E
+     *         If an error occurred when parsing the attribute.
      */
-    public <T> Set<T> asSetOf(final Function<ByteString, ? extends T, NeverThrowsException> f,
-            final Collection<? extends T> defaultValues) {
+    public <T, E extends Exception> Set<T> asSetOf(final Function<ByteString, ? extends T, E> f,
+            final Collection<? extends T> defaultValues) throws E {
         if (!isEmpty(attribute)) {
             final LinkedHashSet<T> result = new LinkedHashSet<>(attribute.size());
             for (final ByteString b : attribute) {
@@ -342,17 +353,21 @@
      *
      * @param <T>
      *            The type of the values to be decoded.
+     * @param <E>
+     *            The type of exception thrown by the function.
      * @param f
      *            The function which should be used to decode values.
      * @param defaultValues
      *            The default values to return if the attribute is empty.
      * @return The values decoded as a set of {@code T}s.
+     * @throws E
+     *         If an error occurred when parsing the attribute.
      */
     @SafeVarargs
     @SuppressWarnings("varargs")
-    public final <T> Set<T> asSetOf(final Function<ByteString, ? extends T, NeverThrowsException> f,
-            final T... defaultValues) {
-        return asSetOf(f, Arrays.asList(defaultValues));
+    public final <T, E extends Exception> Set<T> asSetOf(final Function<ByteString, ? extends T, E> f,
+            final T... defaultValues) throws E {
+        return asSetOf(f, asList(defaultValues));
     }
 
     /**
@@ -377,7 +392,7 @@
      */
     public Set<AttributeDescription> asSetOfAttributeDescription(
             final AttributeDescription... defaultValues) {
-        return asSetOfAttributeDescription(Arrays.asList(defaultValues));
+        return asSetOfAttributeDescription(asList(defaultValues));
     }
 
     /**
@@ -389,9 +404,8 @@
      *            The default values to return if the attribute is empty.
      * @return The values decoded as a set of {@code AttributeDescription}s.
      */
-    public Set<AttributeDescription> asSetOfAttributeDescription(
-            final Collection<AttributeDescription> defaultValues) {
-        return asSetOf(Functions.byteStringToAttributeDescription(), defaultValues);
+    public Set<AttributeDescription> asSetOfAttributeDescription(final Collection<AttributeDescription> defaultValues) {
+        return asSetOf(byteStringToAttributeDescription(), defaultValues);
     }
 
     /**
@@ -404,8 +418,8 @@
      * @return The values decoded as a set of {@code AttributeDescription}s.
      */
     public Set<AttributeDescription> asSetOfAttributeDescription(final String... defaultValues) {
-        return asSetOfAttributeDescription(transformedCollection(Arrays.asList(defaultValues),
-                Functions.stringToAttributeDescription(getSchema()), null));
+        return asSetOfAttributeDescription(transformedCollection(asList(defaultValues),
+                                                                 stringToAttributeDescription(getSchema()), null));
     }
 
     /**
@@ -417,7 +431,7 @@
      * @return The values decoded as a set of {@code Boolean}s.
      */
     public Set<Boolean> asSetOfBoolean(final Boolean... defaultValues) {
-        return asSetOfBoolean(Arrays.asList(defaultValues));
+        return asSetOfBoolean(asList(defaultValues));
     }
 
     /**
@@ -429,7 +443,7 @@
      * @return The values decoded as a set of {@code Boolean}s.
      */
     public Set<Boolean> asSetOfBoolean(final Collection<Boolean> defaultValues) {
-        return asSetOf(Functions.byteStringToBoolean(), defaultValues);
+        return asSetOf(byteStringToBoolean(), defaultValues);
     }
 
     /**
@@ -441,7 +455,7 @@
      * @return The values contained in the attribute.
      */
     public Set<ByteString> asSetOfByteString(final ByteString... defaultValues) {
-        return asSetOfByteString(Arrays.asList(defaultValues));
+        return asSetOfByteString(asList(defaultValues));
     }
 
     /**
@@ -477,7 +491,7 @@
      * @return The values decoded as a set of {@code DN}s.
      */
     public Set<DN> asSetOfDN(final Collection<DN> defaultValues) {
-        return asSetOf(Functions.byteStringToDN(), defaultValues);
+        return asSetOf(byteStringToDN(), defaultValues);
     }
 
     /**
@@ -490,7 +504,7 @@
      * @return The values decoded as a set of {@code DN}s.
      */
     public Set<DN> asSetOfDN(final DN... defaultValues) {
-        return asSetOfDN(Arrays.asList(defaultValues));
+        return asSetOfDN(asList(defaultValues));
     }
 
     /**
@@ -503,8 +517,7 @@
      * @return The values decoded as a set of {@code DN}s.
      */
     public Set<DN> asSetOfDN(final String... defaultValues) {
-        return asSetOfDN(transformedCollection(Arrays.asList(defaultValues), Functions
-                .stringToDN(getSchema()), null));
+        return asSetOfDN(transformedCollection(asList(defaultValues), stringToDN(getSchema()), null));
     }
 
     /**
@@ -516,9 +529,8 @@
      *            The default values to return if the attribute is empty.
      * @return The values decoded as a set of {@code GeneralizedTime}s.
      */
-    public Set<GeneralizedTime> asSetOfGeneralizedTime(
-            final Collection<GeneralizedTime> defaultValues) {
-        return asSetOf(Functions.byteStringToGeneralizedTime(), defaultValues);
+    public Set<GeneralizedTime> asSetOfGeneralizedTime(final Collection<GeneralizedTime> defaultValues) {
+        return asSetOf(byteStringToGeneralizedTime(), defaultValues);
     }
 
     /**
@@ -531,7 +543,7 @@
      * @return The values decoded as a set of {@code GeneralizedTime}s.
      */
     public Set<GeneralizedTime> asSetOfGeneralizedTime(final GeneralizedTime... defaultValues) {
-        return asSetOfGeneralizedTime(Arrays.asList(defaultValues));
+        return asSetOfGeneralizedTime(asList(defaultValues));
     }
 
     /**
@@ -543,7 +555,7 @@
      * @return The values decoded as a set of {@code Integer}s.
      */
     public Set<Integer> asSetOfInteger(final Collection<Integer> defaultValues) {
-        return asSetOf(Functions.byteStringToInteger(), defaultValues);
+        return asSetOf(byteStringToInteger(), defaultValues);
     }
 
     /**
@@ -555,7 +567,7 @@
      * @return The values decoded as a set of {@code Integer}s.
      */
     public Set<Integer> asSetOfInteger(final Integer... defaultValues) {
-        return asSetOfInteger(Arrays.asList(defaultValues));
+        return asSetOfInteger(asList(defaultValues));
     }
 
     /**
@@ -567,7 +579,7 @@
      * @return The values decoded as a set of {@code Long}s.
      */
     public Set<Long> asSetOfLong(final Collection<Long> defaultValues) {
-        return asSetOf(Functions.byteStringToLong(), defaultValues);
+        return asSetOf(byteStringToLong(), defaultValues);
     }
 
     /**
@@ -579,7 +591,7 @@
      * @return The values decoded as a set of {@code Long}s.
      */
     public Set<Long> asSetOfLong(final Long... defaultValues) {
-        return asSetOfLong(Arrays.asList(defaultValues));
+        return asSetOfLong(asList(defaultValues));
     }
 
     /**
@@ -591,7 +603,7 @@
      * @return The values decoded as a set of {@code String}s.
      */
     public Set<String> asSetOfString(final Collection<String> defaultValues) {
-        return asSetOf(Functions.byteStringToString(), defaultValues);
+        return asSetOf(byteStringToString(), defaultValues);
     }
 
     /**
@@ -603,7 +615,7 @@
      * @return The values decoded as a set of {@code String}s.
      */
     public Set<String> asSetOfString(final String... defaultValues) {
-        return asSetOfString(Arrays.asList(defaultValues));
+        return asSetOfString(asList(defaultValues));
     }
 
     /**
@@ -625,7 +637,7 @@
      * @return The first value decoded as a {@code String}.
      */
     public String asString(final String defaultValue) {
-        return as(Functions.byteStringToString(), defaultValue);
+        return as(byteStringToString(), defaultValue);
     }
 
     /**
diff --git a/opendj-core/src/main/java/org/forgerock/opendj/ldap/Functions.java b/opendj-core/src/main/java/org/forgerock/opendj/ldap/Functions.java
index 6c5465e..79141a0 100644
--- a/opendj-core/src/main/java/org/forgerock/opendj/ldap/Functions.java
+++ b/opendj-core/src/main/java/org/forgerock/opendj/ldap/Functions.java
@@ -70,8 +70,8 @@
                 }
             };
 
-    private static final Function<String, Boolean, NeverThrowsException> STRING_TO_BOOLEAN =
-            new Function<String, Boolean, NeverThrowsException>() {
+    private static final Function<String, Boolean, LocalizedIllegalArgumentException> STRING_TO_BOOLEAN =
+            new Function<String, Boolean, LocalizedIllegalArgumentException>() {
                 @Override
                 public Boolean apply(final String value) {
                     final String valueString = StaticUtils.toLowerCase(value);
@@ -88,16 +88,16 @@
                 }
             };
 
-    private static final Function<String, GeneralizedTime, NeverThrowsException> STRING_TO_GENERALIZED_TIME =
-            new Function<String, GeneralizedTime, NeverThrowsException>() {
+    private static final Function<String, GeneralizedTime, LocalizedIllegalArgumentException> STRING_TO_GTIME =
+            new Function<String, GeneralizedTime, LocalizedIllegalArgumentException>() {
                 @Override
                 public GeneralizedTime apply(final String value) {
                     return GeneralizedTime.valueOf(value);
                 }
             };
 
-    private static final Function<String, Integer, NeverThrowsException> STRING_TO_INTEGER =
-            new Function<String, Integer, NeverThrowsException>() {
+    private static final Function<String, Integer, LocalizedIllegalArgumentException> STRING_TO_INTEGER =
+            new Function<String, Integer, LocalizedIllegalArgumentException>() {
                 @Override
                 public Integer apply(final String value) {
                     try {
@@ -109,8 +109,8 @@
                 }
             };
 
-    private static final Function<String, Long, NeverThrowsException> STRING_TO_LONG =
-            new Function<String, Long, NeverThrowsException>() {
+    private static final Function<String, Long, LocalizedIllegalArgumentException> STRING_TO_LONG =
+            new Function<String, Long, LocalizedIllegalArgumentException>() {
                 @Override
                 public Long apply(final String value) {
                     try {
@@ -122,17 +122,18 @@
                 }
             };
 
-    private static final Function<ByteString, Boolean, NeverThrowsException> BYTESTRING_TO_BOOLEAN = compose(
-            byteStringToString(), STRING_TO_BOOLEAN);
+    private static final Function<ByteString, Boolean, LocalizedIllegalArgumentException> BYTESTRING_TO_BOOLEAN =
+            compose(byteStringToString(), STRING_TO_BOOLEAN);
 
-    private static final Function<ByteString, GeneralizedTime, NeverThrowsException> BYTESTRING_TO_GENERALIZED_TIME =
-            compose(byteStringToString(), STRING_TO_GENERALIZED_TIME);
 
-    private static final Function<ByteString, Integer, NeverThrowsException> BYTESTRING_TO_INTEGER = compose(
-            byteStringToString(), STRING_TO_INTEGER);
+    private static final Function<ByteString, GeneralizedTime, LocalizedIllegalArgumentException> BYTESTRING_TO_GTIME =
+            compose(byteStringToString(), STRING_TO_GTIME);
 
-    private static final Function<ByteString, Long, NeverThrowsException> BYTESTRING_TO_LONG = compose(
-            byteStringToString(), STRING_TO_LONG);
+    private static final Function<ByteString, Integer, LocalizedIllegalArgumentException> BYTESTRING_TO_INTEGER =
+            compose(byteStringToString(), STRING_TO_INTEGER);
+
+    private static final Function<ByteString, Long, LocalizedIllegalArgumentException> BYTESTRING_TO_LONG =
+            compose(byteStringToString(), STRING_TO_LONG);
 
     /**
      * Creates a function that returns constant value for any input.
@@ -165,17 +166,19 @@
      * @param <X>
      *            The type of intermediate values passed between the two
      *            functions.
+     * @param <E>
+     *            The type of exception thrown by the {@code second} function.
      * @param first
      *            The first function which will consume the input.
      * @param second
      *            The second function which will produce the result.
      * @return The composition.
      */
-    public static <M, X, N> Function<M, N, NeverThrowsException> compose(
-            final Function<M, X, NeverThrowsException> first, final Function<X, N, NeverThrowsException> second) {
-        return new Function<M, N, NeverThrowsException>() {
+    public static <M, X, N, E extends Exception> Function<M, N, E> compose(
+            final Function<M, X, NeverThrowsException> first, final Function<X, N, E> second) {
+        return new Function<M, N, E>() {
             @Override
-            public N apply(final M value) {
+            public N apply(final M value) throws E {
                 return second.apply(first.apply(value));
             }
         };
@@ -224,7 +227,8 @@
      *
      * @return A function which parses {@code AttributeDescription}s.
      */
-    public static Function<String, AttributeDescription, NeverThrowsException> stringToAttributeDescription() {
+    public static Function<String, AttributeDescription, LocalizedIllegalArgumentException>
+    stringToAttributeDescription() {
         return stringToAttributeDescription(getDefaultSchema());
     }
 
@@ -237,9 +241,9 @@
      *            The schema to use for decoding attribute descriptions.
      * @return A function which parses {@code AttributeDescription}s.
      */
-    public static Function<String, AttributeDescription, NeverThrowsException> stringToAttributeDescription(
-            final Schema schema) {
-        return new Function<String, AttributeDescription, NeverThrowsException>() {
+    public static Function<String, AttributeDescription, LocalizedIllegalArgumentException>
+    stringToAttributeDescription(final Schema schema) {
+        return new Function<String, AttributeDescription, LocalizedIllegalArgumentException>() {
             @Override
             public AttributeDescription apply(final String value) {
                 return AttributeDescription.valueOf(value, schema);
@@ -251,11 +255,11 @@
      * Returns a function which parses {@code Boolean} values. The function will
      * accept the values {@code 0}, {@code false}, {@code no}, {@code off},
      * {@code 1}, {@code true}, {@code yes}, {@code on}. All other values will
-     * result in a {@code NumberFormatException}.
+     * result in a {@code LocalizedIllegalArgumentException}.
      *
      * @return A function which parses {@code Boolean} values.
      */
-    public static Function<String, Boolean, NeverThrowsException> stringToBoolean() {
+    public static Function<String, Boolean, LocalizedIllegalArgumentException> stringToBoolean() {
         return STRING_TO_BOOLEAN;
     }
 
@@ -266,7 +270,7 @@
      *
      * @return A function which parses {@code DN}s.
      */
-    public static Function<String, DN, NeverThrowsException> stringToDN() {
+    public static Function<String, DN, LocalizedIllegalArgumentException> stringToDN() {
         return stringToDN(getDefaultSchema());
     }
 
@@ -279,8 +283,8 @@
      *            The schema to use for decoding DNs.
      * @return A function which parses {@code DN}s.
      */
-    public static Function<String, DN, NeverThrowsException> stringToDN(final Schema schema) {
-        return new Function<String, DN, NeverThrowsException>() {
+    public static Function<String, DN, LocalizedIllegalArgumentException> stringToDN(final Schema schema) {
+        return new Function<String, DN, LocalizedIllegalArgumentException>() {
             @Override
             public DN apply(final String value) {
                 return DN.valueOf(value, schema);
@@ -294,8 +298,8 @@
      *
      * @return A function which parses generalized time strings.
      */
-    public static Function<String, GeneralizedTime, NeverThrowsException> stringToGeneralizedTime() {
-        return STRING_TO_GENERALIZED_TIME;
+    public static Function<String, GeneralizedTime, LocalizedIllegalArgumentException> stringToGeneralizedTime() {
+        return STRING_TO_GTIME;
     }
 
     /**
@@ -304,7 +308,7 @@
      *
      * @return A function which parses {@code Integer} string values.
      */
-    public static Function<String, Integer, NeverThrowsException> stringToInteger() {
+    public static Function<String, Integer, LocalizedIllegalArgumentException> stringToInteger() {
         return STRING_TO_INTEGER;
     }
 
@@ -314,7 +318,7 @@
      *
      * @return A function which parses {@code Long} string values.
      */
-    public static Function<String, Long, NeverThrowsException> stringToLong() {
+    public static Function<String, Long, LocalizedIllegalArgumentException> stringToLong() {
         return STRING_TO_LONG;
     }
 
@@ -325,7 +329,8 @@
      *
      * @return A function which parses {@code AttributeDescription}s.
      */
-    public static Function<ByteString, AttributeDescription, NeverThrowsException> byteStringToAttributeDescription() {
+    public static Function<ByteString, AttributeDescription, LocalizedIllegalArgumentException>
+    byteStringToAttributeDescription() {
         return byteStringToAttributeDescription(getDefaultSchema());
     }
 
@@ -338,25 +343,20 @@
      *            The schema to use for decoding attribute descriptions.
      * @return A function which parses {@code AttributeDescription}s.
      */
-    public static Function<ByteString, AttributeDescription, NeverThrowsException> byteStringToAttributeDescription(
-            final Schema schema) {
-        return compose(byteStringToString(), new Function<String, AttributeDescription, NeverThrowsException>() {
-            @Override
-            public AttributeDescription apply(final String value) {
-                return AttributeDescription.valueOf(value, schema);
-            }
-        });
+    public static Function<ByteString, AttributeDescription, LocalizedIllegalArgumentException>
+    byteStringToAttributeDescription(final Schema schema) {
+        return compose(byteStringToString(), stringToAttributeDescription(schema));
     }
 
     /**
      * Returns a function which parses {@code Boolean} values. The function will
      * accept the values {@code 0}, {@code false}, {@code no}, {@code off},
      * {@code 1}, {@code true}, {@code yes}, {@code on}. All other values will
-     * result in a {@code NumberFormatException}.
+     * result in a {@code LocalizedIllegalArgumentException}.
      *
      * @return A function which parses {@code Boolean} values.
      */
-    public static Function<ByteString, Boolean, NeverThrowsException> byteStringToBoolean() {
+    public static Function<ByteString, Boolean, LocalizedIllegalArgumentException> byteStringToBoolean() {
         return BYTESTRING_TO_BOOLEAN;
     }
 
@@ -367,7 +367,7 @@
      *
      * @return A function which parses {@code DN}s.
      */
-    public static Function<ByteString, DN, NeverThrowsException> byteStringToDN() {
+    public static Function<ByteString, DN, LocalizedIllegalArgumentException> byteStringToDN() {
         return byteStringToDN(getDefaultSchema());
     }
 
@@ -380,13 +380,8 @@
      *            The schema to use for decoding DNs.
      * @return A function which parses {@code DN}s.
      */
-    public static Function<ByteString, DN, NeverThrowsException> byteStringToDN(final Schema schema) {
-        return compose(byteStringToString(), new Function<String, DN, NeverThrowsException>() {
-            @Override
-            public DN apply(final String value) {
-                return DN.valueOf(value, schema);
-            }
-        });
+    public static Function<ByteString, DN, LocalizedIllegalArgumentException> byteStringToDN(final Schema schema) {
+        return compose(byteStringToString(), stringToDN(schema));
     }
 
     /**
@@ -395,8 +390,9 @@
      *
      * @return A function which parses generalized time strings.
      */
-    public static Function<ByteString, GeneralizedTime, NeverThrowsException> byteStringToGeneralizedTime() {
-        return BYTESTRING_TO_GENERALIZED_TIME;
+    public static Function<ByteString, GeneralizedTime, LocalizedIllegalArgumentException>
+    byteStringToGeneralizedTime() {
+        return BYTESTRING_TO_GTIME;
     }
 
     /**
@@ -405,7 +401,7 @@
      *
      * @return A function which parses {@code Integer} string values.
      */
-    public static Function<ByteString, Integer, NeverThrowsException> byteStringToInteger() {
+    public static Function<ByteString, Integer, LocalizedIllegalArgumentException> byteStringToInteger() {
         return BYTESTRING_TO_INTEGER;
     }
 
@@ -415,7 +411,7 @@
      *
      * @return A function which parses {@code Long} string values.
      */
-    public static Function<ByteString, Long, NeverThrowsException> byteStringToLong() {
+    public static Function<ByteString, Long, LocalizedIllegalArgumentException> byteStringToLong() {
         return BYTESTRING_TO_LONG;
     }
 
diff --git a/opendj-core/src/main/java/org/forgerock/opendj/ldap/RootDSE.java b/opendj-core/src/main/java/org/forgerock/opendj/ldap/RootDSE.java
index 5f73484..6dbe03f 100644
--- a/opendj-core/src/main/java/org/forgerock/opendj/ldap/RootDSE.java
+++ b/opendj-core/src/main/java/org/forgerock/opendj/ldap/RootDSE.java
@@ -16,6 +16,10 @@
  */
 package org.forgerock.opendj.ldap;
 
+import static com.forgerock.opendj.util.Collections2.transformedCollection;
+import static java.util.Collections.unmodifiableCollection;
+import static org.forgerock.opendj.ldap.Functions.objectToByteString;
+
 import java.util.Collection;
 import java.util.Collections;
 
@@ -25,9 +29,6 @@
 import org.forgerock.opendj.ldap.schema.CoreSchema;
 import org.forgerock.util.Reject;
 import org.forgerock.util.Function;
-import org.forgerock.util.promise.NeverThrowsException;
-
-import com.forgerock.opendj.util.Collections2;
 
 /**
  * The root DSE is a DSA-specific Entry (DSE) and not part of any naming context
@@ -398,9 +399,8 @@
         return getSingleValuedAttribute(ATTR_FULL_VENDOR_VERSION, Functions.byteStringToString());
     }
 
-    private <N> Collection<N> getMultiValuedAttribute(
-            final AttributeDescription attributeDescription,
-        final Function<ByteString, N, NeverThrowsException> function) {
+    private <N, E extends RuntimeException> Collection<N> getMultiValuedAttribute(
+            final AttributeDescription attributeDescription, final Function<ByteString, N, E> function) {
         // The returned collection is unmodifiable because we may need to
         // return an empty collection if the attribute does not exist in the
         // underlying entry. If a value is then added to the returned empty
@@ -408,14 +408,13 @@
         // underlying entry in order to maintain consistency.
         final Attribute attr = entry.getAttribute(attributeDescription);
         if (attr != null) {
-            return Collections.unmodifiableCollection(Collections2.transformedCollection(attr,
-                    function, Functions.objectToByteString()));
+            return unmodifiableCollection(transformedCollection(attr, function, objectToByteString()));
         }
         return Collections.emptySet();
     }
 
-    private <N> N getSingleValuedAttribute(final AttributeDescription attributeDescription,
-        final Function<ByteString, N, NeverThrowsException> function) {
+    private <N, E extends Exception> N getSingleValuedAttribute(
+            final AttributeDescription attributeDescription, final Function<ByteString, N, E> function) throws E {
         final Attribute attr = entry.getAttribute(attributeDescription);
         if (attr != null && !attr.isEmpty()) {
             return function.apply(attr.firstValue());
diff --git a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/SimplePropertyMapper.java b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/SimplePropertyMapper.java
index 525e33d..c78d863 100644
--- a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/SimplePropertyMapper.java
+++ b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/SimplePropertyMapper.java
@@ -34,7 +34,6 @@
 import org.forgerock.opendj.ldap.schema.CoreSchema;
 import org.forgerock.services.context.Context;
 import org.forgerock.util.Function;
-import org.forgerock.util.promise.NeverThrowsException;
 import org.forgerock.util.promise.Promise;
 
 import static java.util.Collections.*;
@@ -47,8 +46,8 @@
 
 /** An property mapper which provides a simple mapping from a JSON value to a single LDAP attribute. */
 public final class SimplePropertyMapper extends AbstractLdapPropertyMapper<SimplePropertyMapper> {
-    private Function<ByteString, ?, NeverThrowsException> decoder;
-    private Function<Object, ByteString, NeverThrowsException> encoder;
+    private Function<ByteString, ?, ? extends Exception> decoder;
+    private Function<Object, ByteString, ? extends Exception> encoder;
 
     SimplePropertyMapper(final AttributeDescription ldapAttributeName) {
         super(ldapAttributeName);
@@ -62,7 +61,7 @@
      *            The function to use for decoding LDAP attribute values.
      * @return This property mapper.
      */
-    public SimplePropertyMapper decoder(final Function<ByteString, ?, NeverThrowsException> f) {
+    public SimplePropertyMapper decoder(final Function<ByteString, ?, ? extends Exception> f) {
         this.decoder = f;
         return this;
     }
@@ -99,7 +98,7 @@
      *            The function to use for encoding LDAP attribute values.
      * @return This property mapper.
      */
-    public SimplePropertyMapper encoder(final Function<Object, ByteString, NeverThrowsException> f) {
+    public SimplePropertyMapper encoder(final Function<Object, ByteString, ? extends Exception> f) {
         this.encoder = f;
         return this;
     }
@@ -193,11 +192,11 @@
         }
     }
 
-    private Function<ByteString, ?, NeverThrowsException> decoder() {
+    private Function<ByteString, ?, ? extends Exception> decoder() {
         return decoder == null ? byteStringToJson(ldapAttributeName) : decoder;
     }
 
-    private Function<Object, ByteString, NeverThrowsException> encoder() {
+    private Function<Object, ByteString, ? extends Exception> encoder() {
         return encoder == null ? jsonToByteString(ldapAttributeName) : encoder;
     }
 
diff --git a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Utils.java b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Utils.java
index 042b591..83dc801 100644
--- a/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Utils.java
+++ b/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Utils.java
@@ -106,7 +106,7 @@
     }
 
     static Attribute jsonToAttribute(final Object value, final AttributeDescription ad,
-            final Function<Object, ByteString, NeverThrowsException> f) {
+            final Function<Object, ByteString, ? extends Exception> f) throws Exception {
         if (isJsonPrimitive(value)) {
             return new LinkedAttribute(ad, f.apply(value));
         } else if (value instanceof Collection<?>) {
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/protocols/http/rest2ldap/AdminEndpoint.java b/opendj-server-legacy/src/main/java/org/opends/server/protocols/http/rest2ldap/AdminEndpoint.java
index 2519aaa..96093f7 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/protocols/http/rest2ldap/AdminEndpoint.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/protocols/http/rest2ldap/AdminEndpoint.java
@@ -81,7 +81,6 @@
 import org.forgerock.services.context.Context;
 import org.forgerock.util.Factory;
 import org.forgerock.util.Function;
-import org.forgerock.util.promise.NeverThrowsException;
 import org.forgerock.util.promise.Promise;
 import org.opends.server.api.HttpEndpoint;
 import org.opends.server.core.ServerContext;
@@ -344,7 +343,7 @@
             final DefinedDefaultBehaviorProvider<?> ddbp = (DefinedDefaultBehaviorProvider) dbp;
             final Collection<String> defaultValues = ddbp.getDefaultValues();
             final List<Object> decodedDefaultValues = new ArrayList<>(defaultValues.size());
-            final Function<String, ?, NeverThrowsException> converter = getConverter(attributeName);
+            final Function<String, ?, ? extends RuntimeException> converter = getConverter(attributeName);
             for (final String defaultValue : defaultValues)
             {
               decodedDefaultValues.add(converter.apply(defaultValue));
@@ -356,7 +355,7 @@
       }
     }
 
-    private Function<String, ?, NeverThrowsException> getConverter(final String attributeName)
+    private Function<String, ?, ? extends RuntimeException> getConverter(final String attributeName)
     {
       final AttributeDescription attributeDescription = AttributeDescription.valueOf(attributeName);
       final Syntax syntax = attributeDescription.getAttributeType().getSyntax();
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/types/AttributeParser.java b/opendj-server-legacy/src/main/java/org/opends/server/types/AttributeParser.java
index b087696..5cf12fd 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/types/AttributeParser.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/types/AttributeParser.java
@@ -26,7 +26,6 @@
 import org.forgerock.opendj.ldap.GeneralizedTime;
 import org.forgerock.opendj.ldap.schema.Schema;
 import org.forgerock.util.Function;
-import org.forgerock.util.promise.NeverThrowsException;
 
 
 /**
@@ -91,11 +90,15 @@
      *
      * @param <T>
      *            The type of the value to be decoded.
+     * @param <E>
+     *            The type of exception thrown by the function.
      * @param f
      *            The function which should be used to decode the value.
      * @return The first value decoded as a {@code T}.
+     * @throws E
+     *         If an error occurred when parsing the attribute.
      */
-    public <T> T as(final Function<ByteString, ? extends T, NeverThrowsException> f) {
+    public <T, E extends Exception> T as(final Function<ByteString, ? extends T, E> f) throws E {
         return as(f, null);
     }
 
@@ -106,13 +109,17 @@
      *
      * @param <T>
      *            The type of the value to be decoded.
+     * @param <E>
+     *            The type of exception thrown by the function.
      * @param f
      *            The function which should be used to decode the value.
      * @param defaultValue
      *            The default value to return if the attribute is empty.
      * @return The first value decoded as a {@code T}.
+     * @throws E
+     *         If an error occurred when parsing the attribute.
      */
-    public <T> T as(final Function<ByteString, ? extends T, NeverThrowsException> f, final T defaultValue) {
+    public <T, E extends Exception> T as(final Function<ByteString, ? extends T, E> f, final T defaultValue) throws E {
         if (!isEmpty(attribute)) {
             return f.apply(attribute.iterator().next());
         } else {
@@ -239,14 +246,18 @@
      *
      * @param <T>
      *            The type of the values to be decoded.
+     * @param <E>
+     *            The type of exception thrown by the function.
      * @param f
      *            The function which should be used to decode values.
      * @param defaultValues
      *            The default values to return if the attribute is empty.
      * @return The values decoded as a set of {@code T}s.
+     * @throws E
+     *         If an error occurred when parsing the attribute.
      */
-    public <T> Set<T> asSetOf(final Function<ByteString, ? extends T, NeverThrowsException> f,
-            final Collection<? extends T> defaultValues) {
+    public <T, E extends Exception> Set<T> asSetOf(final Function<ByteString, ? extends T, E> f,
+            final Collection<? extends T> defaultValues) throws E {
         if (!isEmpty(attribute)) {
             final LinkedHashSet<T> result = new LinkedHashSet<>(attribute.size());
             for (final ByteString v : attribute) {
@@ -267,14 +278,18 @@
      *
      * @param <T>
      *            The type of the values to be decoded.
+     * @param <E>
+     *            The type of exception thrown by the function.
      * @param f
      *            The function which should be used to decode values.
      * @param defaultValues
      *            The default values to return if the attribute is empty.
      * @return The values decoded as a set of {@code T}s.
+     * @throws E
+     *         If an error occurred when parsing the attribute.
      */
-    public <T> Set<T> asSetOf(final Function<ByteString, ? extends T, NeverThrowsException> f,
-            final T... defaultValues) {
+    public <T, E extends Exception> Set<T> asSetOf(final Function<ByteString, ? extends T, E> f,
+            final T... defaultValues) throws E {
         return asSetOf(f, Arrays.asList(defaultValues));
     }
 

--
Gitblit v1.10.0