@Override
	public <T> T generate(Class<T> spec, DBObject dbObject) {

		if(dbObject == null) return null;
		
		Constructor constructor = getDefaultConstructor(spec);

		Object entity = invoke(constructor);

		for (Field field : spec.getDeclaredFields()) {

			if (!dbObject.containsField(field.getName())) {
				continue;
			}

			Object fieldValue = null;

			if (field.getAnnotation(SubDocument.class) != null) {
				fieldValue = generate(field.getType(), (BasicDBObject) dbObject.get(field.getName()));
			} 
			else if(Collection.class.isAssignableFrom(field.getType())) {
				
				Class targetClazz = field.getType();

				CollectionSpec collectionSpec = field.getAnnotation(CollectionSpec.class);
				
				if(collectionSpec != null)
					targetClazz = collectionSpec.type();
				
				Object o = dbObject.get(field.getName());
				
				List<Object> list = CollectionFactory.newList();
				
				if(o != null && BasicDBList.class.isAssignableFrom(o.getClass())) {
					BasicDBList values = (BasicDBList) o;
					
					for (Object object : values) {						
						list.add(fieldValueDecoder.decode(targetClazz, object));
					}
				}
				
				fieldValue = list;
			}	
			else {
				fieldValue = fieldValueDecoder.decode(field.getType(), dbObject.get(field.getName()));
			}
			
			setFieldValue(entity, field, fieldValue);
		}

		return (T) entity;
	}