diff --git a/Dorkbox-Util/src/dorkbox/util/entropy/Entropy.java b/Dorkbox-Util/src/dorkbox/util/entropy/Entropy.java
new file mode 100644
index 0000000..fd0866b
--- /dev/null
+++ b/Dorkbox-Util/src/dorkbox/util/entropy/Entropy.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2010 dorkbox, llc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package dorkbox.util.entropy;
+
+import dorkbox.network.util.exceptions.InitializationException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.lang.reflect.Method;
+
+public final
+class Entropy {
+
+ @SuppressWarnings("StaticNonFinalField")
+ private static EntropyProvider provider = null;
+
+ /**
+ * Starts the process, and gets, the next amount of entropy bytes
+ */
+ public static
+ byte[] get(String messageForUser) throws InitializationException {
+ synchronized (Entropy.class) {
+ try {
+ if (provider == null) {
+ Entropy.init(SimpleEntropy.class);
+ }
+
+ return provider.get(messageForUser);
+ } catch (Exception e) {
+ Logger logger = LoggerFactory.getLogger(Entropy.class);
+ String error = "Unable to get entropy bytes for " + provider.getClass();
+ logger.error(error, e);
+ throw new InitializationException(error);
+ }
+ }
+ }
+
+ /**
+ * Will only set the Entropy provider if it has not ALREADY been set!
+ */
+ public static
+ void init(Class extends EntropyProvider> providerClass, Object... args) throws InitializationException {
+ synchronized (Entropy.class) {
+ if (provider == null) {
+ Exception exception = null;
+
+ // use reflection to create the provider.
+ try {
+ Method createMethod = null;
+ Method[] declaredMethods = providerClass.getDeclaredMethods();
+ for (Method m : declaredMethods) {
+ if (m.getName()
+ .equals("create")) {
+ createMethod = m;
+ break;
+ }
+ }
+
+ if (createMethod != null) {
+ createMethod.setAccessible(true);
+
+ if (args.length == 0) {
+ provider = (EntropyProvider) createMethod.invoke(null);
+ }
+ else {
+ provider = (EntropyProvider) createMethod.invoke(null, args);
+ }
+ return;
+ }
+ } catch (Exception e) {
+ exception = e;
+ }
+
+ Logger logger = LoggerFactory.getLogger(Entropy.class);
+ String error = "Unable to create entropy provider for " + providerClass + " with " + args.length + " args";
+ if (exception != null) {
+ logger.error(error, exception);
+ }
+ else {
+ logger.error(error);
+ }
+
+ throw new InitializationException(error);
+ }
+ }
+ }
+
+ private
+ Entropy() {
+ }
+}
diff --git a/Dorkbox-Util/src/dorkbox/util/serializers/ArraysAsListSerializer.java b/Dorkbox-Util/src/dorkbox/util/serializers/ArraysAsListSerializer.java
new file mode 100644
index 0000000..3db9cc2
--- /dev/null
+++ b/Dorkbox-Util/src/dorkbox/util/serializers/ArraysAsListSerializer.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2010 Martin Grotzke
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package dorkbox.util.serializers;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Field;
+import java.util.Arrays;
+import java.util.List;
+
+import com.esotericsoftware.kryo.Kryo;
+import com.esotericsoftware.kryo.Serializer;
+import com.esotericsoftware.kryo.io.Input;
+import com.esotericsoftware.kryo.io.Output;
+
+/**
+ * A kryo {@link Serializer} for lists created via {@link Arrays#asList(Object...)}.
+ *
+ * Note: This serializer does not support cyclic references, so if one of the objects
+ * gets set the list as attribute this might cause an error during deserialization.
+ *
+ *
+ * @author Martin Grotzke
+ */
+public class ArraysAsListSerializer extends Serializer> {
+
+ private Field _arrayField;
+
+ public ArraysAsListSerializer() {
+ try {
+ _arrayField = Class.forName( "java.util.Arrays$ArrayList" ).getDeclaredField( "a" );
+ _arrayField.setAccessible( true );
+ } catch ( final Exception e ) {
+ throw new RuntimeException( e );
+ }
+ // Immutable causes #copy(obj) to return the original object
+ setImmutable(true);
+ }
+
+ @Override
+ public List> read(final Kryo kryo, final Input input, final Class> type) {
+ final int length = input.readInt(true);
+ Class> componentType = kryo.readClass( input ).getType();
+ if (componentType.isPrimitive()) {
+ componentType = getPrimitiveWrapperClass(componentType);
+ }
+ try {
+ final Object items = Array.newInstance( componentType, length );
+ for( int i = 0; i < length; i++ ) {
+ Array.set(items, i, kryo.readClassAndObject( input ));
+ }
+ return Arrays.asList( (Object[])items );
+ } catch ( final Exception e ) {
+ throw new RuntimeException( e );
+ }
+ }
+
+ @Override
+ public void write(final Kryo kryo, final Output output, final List> obj) {
+ try {
+ final Object[] array = (Object[]) _arrayField.get( obj );
+ output.writeInt(array.length, true);
+ final Class> componentType = array.getClass().getComponentType();
+ kryo.writeClass( output, componentType );
+ for( final Object item : array ) {
+ kryo.writeClassAndObject( output, item );
+ }
+ } catch ( final RuntimeException e ) {
+ // Don't eat and wrap RuntimeExceptions because the ObjectBuffer.write...
+ // handles SerializationException specifically (resizing the buffer)...
+ throw e;
+ } catch ( final Exception e ) {
+ throw new RuntimeException( e );
+ }
+ }
+
+ private static Class> getPrimitiveWrapperClass(final Class> c) {
+ if (c.isPrimitive()) {
+ if (c.equals(Long.TYPE)) {
+ return Long.class;
+ } else if (c.equals(Integer.TYPE)) {
+ return Integer.class;
+ } else if (c.equals(Double.TYPE)) {
+ return Double.class;
+ } else if (c.equals(Float.TYPE)) {
+ return Float.class;
+ } else if (c.equals(Boolean.TYPE)) {
+ return Boolean.class;
+ } else if (c.equals(Character.TYPE)) {
+ return Character.class;
+ } else if (c.equals(Short.TYPE)) {
+ return Short.class;
+ } else if (c.equals(Byte.TYPE)) {
+ return Byte.class;
+ }
+ }
+ return c;
+ }
+}
diff --git a/Dorkbox-Util/src/dorkbox/util/serializers/FieldAnnotationAwareSerializer.java b/Dorkbox-Util/src/dorkbox/util/serializers/FieldAnnotationAwareSerializer.java
new file mode 100644
index 0000000..5ea6dca
--- /dev/null
+++ b/Dorkbox-Util/src/dorkbox/util/serializers/FieldAnnotationAwareSerializer.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright 2010 Martin Grotzke
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package dorkbox.util.serializers;
+
+import com.esotericsoftware.kryo.Kryo;
+import com.esotericsoftware.kryo.Serializer;
+import com.esotericsoftware.kryo.factories.SerializerFactory;
+import com.esotericsoftware.kryo.serializers.FieldSerializer;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * A kryo {@link FieldSerializer} that allows to exclusively include or exclude fields that
+ * are attributed with user-specific annotations. This can be for example useful when serializing beans that carry
+ * references to a dependency injection framework. As an example for Spring:
+ *
+ *
+ * {@code
+ * Set> marks = new HashSet<>();
+ * marks.add(Autowired.class);
+ * SerializerFactory disregardingFactory = new FieldAnnotationAwareSerializer.Factory(marks, true);
+ * Kryo kryo = new Kryo();
+ * kryo.setDefaultSerializer(factory);
+ * }
+ *
+ *
+ * The resulting {@link Kryo} instance would ignore all fields that are annotated with Spring's {@code @Autowired}
+ * annotation.
+ *
+ * Similarly, it is possible to created a serializer which does the opposite such that the resulting serializer
+ * would only serialize fields that are annotated with the specified annotations.
+ *
+ * @author Rafael Winterhalter
+ * @author Martin Grotzke
+ */
+public class FieldAnnotationAwareSerializer extends FieldSerializer {
+
+ /**
+ * A factory for creating instances of {@link FieldAnnotationAwareSerializer}.
+ */
+ public static class Factory implements SerializerFactory {
+
+ private final Collection> marked;
+ private final boolean disregarding;
+
+ /**
+ * Creates a new factory. See {@link FieldAnnotationAwareSerializer#FieldAnnotationAwareSerializer(
+ *com.esotericsoftware.kryo.Kryo, Class, java.util.Collection, boolean)}
+ * for additional information on the constructor parameters.
+ *
+ * @param marked The annotations that will be considered of the resulting converter.
+ * @param disregarding If {@code true}, the serializer will ignore all annotated fields,
+ * if set to {@code false} it will exclusively look at annotated fields.
+ */
+ public Factory(final Collection> marked, final boolean disregarding) {
+ this.marked = marked;
+ this.disregarding = disregarding;
+ }
+
+ @Override
+ public Serializer> makeSerializer(final Kryo kryo, final Class> type) {
+ return new FieldAnnotationAwareSerializer