diff --git a/src/main/java/teetime/stage/basic/distributor/CloneStrategy.java b/src/main/java/teetime/stage/basic/distributor/CloneStrategy.java
index 1264c6b81c8c187a1b9b29ff7fe4408ef0ca9bea..46ed05883ddf17bc070d585232535ac680ef26ae 100644
--- a/src/main/java/teetime/stage/basic/distributor/CloneStrategy.java
+++ b/src/main/java/teetime/stage/basic/distributor/CloneStrategy.java
@@ -15,6 +15,12 @@
  */
 package teetime.stage.basic.distributor;
 
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
 import teetime.framework.OutputPort;
 
 /**
@@ -26,7 +32,83 @@ public final class CloneStrategy implements IDistributorStrategy {
 
 	@Override
 	public <T> boolean distribute(final OutputPort<T>[] outputPorts, final T element) {
-		throw new UnsupportedOperationException();
+		for (final OutputPort<T> outputPort : outputPorts) {
+			outputPort.send(clone(element));
+		}
+
+		return true;
+	}
+
+	@SuppressWarnings("unchecked")
+	private static <T> T clone(final T element) {
+		try {
+			final T newInstance = (T) element.getClass().newInstance();
+
+			final Collection<Method> setters = findSetters(element.getClass());
+			final Collection<Method> getters = findGetters(element.getClass());
+
+			for (Method setter : setters) {
+				final Method getter = findCorrespondingGetter(setter, getters);
+				if (getter != null) {
+					setter.invoke(newInstance, getter.invoke(element, new Object[0]));
+				}
+			}
+
+			return newInstance;
+		} catch (InstantiationException e) {
+			throw new UnsupportedOperationException();
+		} catch (IllegalAccessException e) {
+			throw new UnsupportedOperationException();
+		} catch (IllegalArgumentException e) {
+			throw new UnsupportedOperationException();
+		} catch (InvocationTargetException e) {
+			throw new UnsupportedOperationException();
+		}
+	}
+
+	private static Collection<Method> findSetters(final Class<?> clazz) {
+		final List<Method> methods = new ArrayList<Method>();
+
+		for (Method method : clazz.getMethods()) {
+			if (method.getReturnType() == Void.TYPE) {
+				if (method.getParameterCount() == 1) {
+					if (method.getName().matches("set[A-Z].*")) {
+						methods.add(method);
+					}
+				}
+			}
+		}
+
+		return methods;
+	}
+
+	private static Collection<Method> findGetters(final Class<?> clazz) {
+		final List<Method> methods = new ArrayList<Method>();
+
+		for (Method method : clazz.getMethods()) {
+			if (method.getReturnType() != Void.TYPE) {
+				if (method.getParameterCount() == 0) {
+					if (method.getName().matches("get[A-Z].*") || method.getName().matches("is[A-Z].*")) {
+						methods.add(method);
+					}
+				}
+			}
+		}
+
+		return methods;
+	}
+
+	private static Method findCorrespondingGetter(final Method setter, final Collection<Method> getters) {
+		final String attributeName = setter.getName().substring(3);
+		for (Method getter : getters) {
+			if (getter.getReturnType() == setter.getParameterTypes()[0]) {
+				if (getter.getName().matches("get" + attributeName) || getter.getName().matches("is" + attributeName)) {
+					return getter;
+				}
+			}
+		}
+
+		return null;
 	}
 
 }
diff --git a/src/test/java/teetime/stage/basic/distributor/DistributorTest.java b/src/test/java/teetime/stage/basic/distributor/DistributorTest.java
index 48521d5247774844b6b1c8c99a4a3d5f2880e80f..0b8e3cda9c42726051af85e33469fc4673147207 100644
--- a/src/test/java/teetime/stage/basic/distributor/DistributorTest.java
+++ b/src/test/java/teetime/stage/basic/distributor/DistributorTest.java
@@ -17,6 +17,7 @@ package teetime.stage.basic.distributor;
 
 import static org.hamcrest.Matchers.contains;
 import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.not;
 import static org.hamcrest.collection.IsEmptyCollection.empty;
 import static org.junit.Assert.assertThat;
 
@@ -105,11 +106,50 @@ public class DistributorTest {
 	}
 
 	@Test
-	public void cloneShouldNotWork() {
+	public void cloneForIntegerShouldNotWork() {
 		distributorUnderTest.setStrategy(new CloneStrategy());
 
 		expectedException.expect(UnsupportedOperationException.class);
 		this.distributorUnderTest.execute(1);
 	}
 
+	@Test
+	public void cloneForSimpleBeanShoulWork() throws Exception {
+		final Distributor<SimpleBean> distributorUnderTest = new Distributor<SimpleBean>(new CloneStrategy());
+		final CollectorSink<SimpleBean> collector = new CollectorSink<SimpleBean>();
+
+		final IPipeFactory pipeFactory = new SingleElementPipeFactory();
+		pipeFactory.create(distributorUnderTest.getNewOutputPort(), collector.getInputPort());
+
+		distributorUnderTest.onStarting();
+
+		final SimpleBean originalBean = new SimpleBean(42);
+		distributorUnderTest.execute(originalBean);
+		final SimpleBean clonedBean = collector.getElements().get(0);
+
+		assertThat(originalBean, is(not(clonedBean)));
+		assertThat(originalBean.getValue(), is(clonedBean.getValue()));
+	}
+
+	private static class SimpleBean {
+
+		private int value;
+
+		@SuppressWarnings("unused")
+		public SimpleBean() {}
+
+		public SimpleBean(final int value) {
+			this.setValue(value);
+		}
+
+		public int getValue() {
+			return value;
+		}
+
+		public void setValue(final int value) {
+			this.value = value;
+		}
+
+	}
+
 }