@SuppressWarnings("unchecked")
	public static Object convertFromProperty(Object value, Class<?> targetType,
			Class<?>componentType, Class<?> concreteFieldType) {
		if (value != null) {
			if (Date.class.isAssignableFrom(targetType) && value instanceof Number) {
				return longToDate(((Number)value).longValue(), targetType);
			} else if (Enum.class.isAssignableFrom(targetType)) {
				Object[] enums=getEnumValues((Class<? extends Enum<?>>) targetType);
				for (int i = 0; i < enums.length; i++) {
					if (((Enum<?>)enums[i]).name().equals(value.toString()))
						return enums[i];
				}
				return value;
			} else if (Collection.class.isAssignableFrom(targetType)) {
				if (componentType != null) {
					List<Object> converted = new ArrayList<>();
					Collection<Object> coll = (Collection<Object>)value;
					for (Object elem : coll) {
						converted.add(convertFromProperty(elem, componentType, null, null));
					}
					try {
						coll.clear();
						coll.addAll(converted);
					} catch (UnsupportedOperationException e) {
						return converted;
					}
				}
			} else if (targetType.isArray()) {
				if (componentType != null) {
					if (value instanceof Collection<?>) {
						List<Object> converted = new ArrayList<>();
						Collection<Object> coll = (Collection<Object>)value;
						for (Object elem : coll) {
							converted.add(convertFromProperty(elem, componentType, null, null));
						}
						if (componentType.isPrimitive()) {
							Object array = Array.newInstance(componentType, coll.size());
							for (int i = 0; i < converted.size(); i++) {
								Array.set(array, i, converted.get(i));
							}
							return array;
						} else {
							try {
								coll.clear();
								coll.addAll(converted);
							} catch (UnsupportedOperationException e) {
								return converted;
							}
						}
					}
				}
			} else if (Map.class.isAssignableFrom(targetType)) { // only possible for empty maps
				if (concreteFieldType != null) {
					try {
						return concreteFieldType.newInstance();
					} catch (Throwable e) {
						throw new RuntimeException(e);
					}
				}
			} else if (targetType.equals(value.getClass())) {
				return value;
			} else if (targetType.isPrimitive()) {
				return convertToPrimitive(value, targetType);
			} else if (targetType.isAssignableFrom(value.getClass())) {
				return targetType.cast(value);
			} else if (Number.class.isAssignableFrom(targetType) && value instanceof Number) {
				return convertToDistinctNumber(value, targetType);
			}
		}
		return value;
	}
@ SuppressWarnings ( "unchecked" ) public static Object convertFromProperty ( Object value , Class < ? > targetType , Class < ? > componentType , Class < ? > concreteFieldType ) { if ( value != null ) { if ( Date . class . isAssignableFrom ( targetType ) && value instanceof Number ) { return longToDate ( ( ( Number ) value ) . longValue ( ) , targetType ) ; } else if ( Enum . class . isAssignableFrom ( targetType ) ) { Object [ ] enums = getEnumValues ( ( Class < ? extends Enum < ? > > ) targetType ) ; for ( int i = 0 ; i < enums . length ; i ++ ) { if ( ( ( Enum < ? > ) enums [ i ] ) . name ( ) . equals ( value . toString ( ) ) ) return enums [ i ] ; } return value ; } else if ( Collection . class . isAssignableFrom ( targetType ) ) { if ( componentType != null ) { List < Object > converted = new ArrayList < > ( ) ; Collection < Object > coll = ( Collection < Object > ) value ; for ( Object elem : coll ) { converted . add ( convertFromProperty ( elem , componentType , null , null ) ) ; } try { coll . clear ( ) ; coll . addAll ( converted ) ; } catch ( UnsupportedOperationException e ) { return converted ; } } } else if ( targetType . isArray ( ) ) { if ( componentType != null ) { if ( value instanceof Collection < ? > ) { List < Object > converted = new ArrayList < > ( ) ; Collection < Object > coll = ( Collection < Object > ) value ; for ( Object elem : coll ) { converted . add ( convertFromProperty ( elem , componentType , null , null ) ) ; } if ( componentType . isPrimitive ( ) ) { Object array = Array . newInstance ( componentType , coll . size ( ) ) ; for ( int i = 0 ; i < converted . size ( ) ; i ++ ) { Array . set ( array , i , converted . get ( i ) ) ; } return array ; } else { try { coll . clear ( ) ; coll . addAll ( converted ) ; } catch ( UnsupportedOperationException e ) { return converted ; } } } } } else if ( Map . class . isAssignableFrom ( targetType ) ) { if ( concreteFieldType != null ) { try { return concreteFieldType . newInstance ( ) ; } catch ( Throwable e ) { throw new RuntimeException ( e ) ; } } } else if ( targetType . equals ( value . getClass ( ) ) ) { return value ; } else if ( targetType . isPrimitive ( ) ) { return convertToPrimitive ( value , targetType ) ; } else if ( targetType . isAssignableFrom ( value . getClass ( ) ) ) { return targetType . cast ( value ) ; } else if ( Number . class . isAssignableFrom ( targetType ) && value instanceof Number ) { return convertToDistinctNumber ( value , targetType ) ; } } return value ; }
@param value
@param targetType
@param componentType may be null in case when targetType is not a collection,
or when the listComponentType cannot be determined
@param concreteFieldType
@return