 			type = Type.forInstance(source);
 		}
 
+		if(!isTypePreparedForCloning(type)) {
+			prepareTypeForCloning(type);
+		}
+
 		const fieldsToClone:Vector.<Field> = findAllWritableFieldsForType(type);
-		const clonedInstance:* = new (type.clazz)();
 
 		for each(var field:Field in fieldsToClone) {
-			PropertyUtil.cloneProperty(source, clonedInstance, field.name);
+//			PropertyUtil.cloneProperty(source, clonedInstance, field.name);
+			var fieldType:Type = field.type;
+			if(isTypeCloneable(fieldType) && !isTypePreparedForCloning(fieldType)) {
+				prepareTypeForCloning(fieldType);
+			}
 		}
+
+		const byteArray:ByteArray = new ByteArray();
+		byteArray.writeObject(source);
+		byteArray.position = 0;
+
+		const clonedInstance:* = byteArray.readObject();
 
 		return clonedInstance;
 	}


public class Cloner {

	private static function isTypeCloneable(type:Type):Boolean {
		return type.hasMetadata(MetadataName.CLONEABLE);
	}

	private static function failIfTypeIsNotCloneable(type:Type):void {

import dolly.core.dolly_internal;
import dolly.core.errors.CloningError;
import dolly.core.metadata.MetadataName;
import dolly.utils.ClassUtil;
import dolly.utils.PropertyUtil;

import flash.utils.ByteArray;

import flash.utils.Dictionary;

