// Path: restler-core/src/test/java/net/researchgate/restdsl/entities/Account.java
// public class Account {
//     private Long id;
// 
//     public Long getId() {
//         return id;
//     }
// 
//     public void setId(Long id) {
//         this.id = id;
//     }
// }
// 
// Path: restler-core/src/main/java/net/researchgate/restdsl/exceptions/RestDslException.java
// public class RestDslException extends RuntimeException {
//     //TODO: generialize types, rethink them.
//     // TODO: need something like generic conflict state
//     public enum Type {
//         // DB constraint violation
//         DUPLICATE_KEY,
// 
//         // Entity provided is not valid
//         ENTITY_ERROR,
// 
//         // Unknown or implementation error
//         GENERAL_ERROR,
// 
//         // params supplied via HTTP are invalid
//         PARAMS_ERROR,
// 
//         // Service query contains errors
//         QUERY_ERROR
//     }
// 
//     // default type
//     private Type type = Type.GENERAL_ERROR;
// 
//     public RestDslException(String message) {
//         super(message);
//     }
// 
//     public RestDslException(String message, Type type) {
//         super(message);
//         this.type = type;
//     }
// 
//     public RestDslException(String message, Throwable cause, Type type) {
//         super(message, cause);
//         this.type = type;
//     }
// 
//     public Type getType() {
//         return type;
//     }
// 
// }
// 
// Path: restler-core/src/main/java/net/researchgate/restdsl/types/TypeInfoUtil.java
// public class TypeInfoUtil {
//     private static final Logger LOGGER = LoggerFactory.getLogger(TypeInfoUtil.class);
// 
//     public static final Mapper MAPPER = new Morphia().getMapper();
// 
//     private static Map<Class, TypeConverter<?>> converters = new HashMap<>();
// 
// 
//     public static void addConverter(TypeConverter<?> converter) {
//         if (converters.containsKey(converter.getType())) {
//             LOGGER.warn("Converter for class " + converter.getType().getName() + " has been already registered");
//         }
//         converters.put(converter.getType(), converter);
//     }
// 
// 
//     //TODO: converters via annotations
//     @SuppressWarnings("unchecked")
//     // fieldName and parentClazz are needed for potential reflection to get serde info from a field
//     public static <K> K getValue(String strVal, String fieldName, Class<K> clazz, Class<?> parentClazz) throws RestDslException {
//         try {
//             ServiceQueryReservedValue reservedValue = ServiceQueryReservedValue.fromString(strVal);
//             if (reservedValue != null) {
//                 if (reservedValue == ServiceQueryReservedValue.NULL) {
//                     return null;
//                 }
//                 return (K) reservedValue;
//             }
//             if (converters.containsKey(clazz)) {
//                 return (K) converters.get(clazz).deserialize(strVal);
//             }
// 
//             if (clazz == String.class) {
//                 return (K) strVal;
//             } else if (clazz == Long.class || clazz == long.class) {
//                 return (K) Long.valueOf(strVal, 10);
//             } else if (clazz == Integer.class || clazz == int.class) {
//                 return (K) Integer.valueOf(strVal, 10);
//             } else if (clazz == ObjectId.class) {
//                 return (K) new ObjectId(strVal);
//             } else if (clazz == Boolean.class || clazz == boolean.class) {
//                 return (K) Boolean.valueOf(strVal);
//             } else if (clazz.isEnum()) {
//                 Class c = clazz;
//                 Converter<String, K> converter = Enums.stringConverter(c);
//                 return converter.convert(strVal);
//             } else if (clazz == Date.class) {
//                 return (K) new Date(Long.valueOf(strVal, 10));
//             }
//         } catch (Exception e) {
//             throw new RestDslException("Cannot convert '" + strVal + "' to object of class " + clazz.getName(), e, RestDslException.Type.PARAMS_ERROR);
//         }
//         throw new RestDslException("Unsupported type " + clazz.getName() + " for value '" + strVal + "'", RestDslException.Type.PARAMS_ERROR);
//     }
// 
// 
//     //TODO: get rid of Pair
//     public static Pair<Class<?>, Class<?>> getFieldExpressionClazz(Class<?> cl, String fieldExpression) throws RestDslException {
//         return getFieldExpressionClazz(cl, null, fieldExpression, Splitter.on('.').splitToList(fieldExpression), 0);
//     }
// 
//     private static Pair<Class<?>, Class<?>> getFieldExpressionClazz(Class<?> cl, Class<?> prevClazz, String fieldExpression, List<String> fields, int ptr) throws RestDslException {
//         if (ptr >= fields.size()) {
//             return Pair.of(cl, prevClazz);
//         }
//         String fieldName = fields.get(ptr);
// 
//         //TODO: cache mapped info
//         MappedClass mc = MAPPER.getMappedClass(cl);
//         MappedField nestedField = mc.getMappedFieldByJavaField(fieldName);
//         if (nestedField == null) {
//             throw new RestDslException("Cannot find field " + fieldExpression, RestDslException.Type.PARAMS_ERROR);
//         }
//         Class<?> nestedClazz = nestedField.getType();
//         //TODO: better type checking
//         if (nestedClazz.isAssignableFrom(List.class)) {
//             Type subType = nestedField.getSubType();
//             return getFieldExpressionClazz((Class<?>) subType, cl, fieldExpression, fields, ptr + 1);
//         } else {
//             return getFieldExpressionClazz(nestedClazz, cl, fieldExpression, fields, ptr + 1);
//         }
//     }
// }


import net.researchgate.restdsl.entities.Account;
import net.researchgate.restdsl.exceptions.RestDslException;
import net.researchgate.restdsl.types.TypeInfoUtil;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
package net.researchgate.restdsl.util;



/**
 * Testing conversion methods
 */
public class TypeInfoUtilTest {

    @Test
    public void testSimple() {
        assertEquals(123L, (Object) TypeInfoUtil.getValue("123", "id", Long.class, Account.class));

        try {
// Path: restler-core/src/test/java/net/researchgate/restdsl/entities/Account.java
// public class Account {
//     private Long id;
// 
//     public Long getId() {
//         return id;
//     }
// 
//     public void setId(Long id) {
//         this.id = id;
//     }
// }
// 
// Path: restler-core/src/main/java/net/researchgate/restdsl/exceptions/RestDslException.java
// public class RestDslException extends RuntimeException {
//     //TODO: generialize types, rethink them.
//     // TODO: need something like generic conflict state
//     public enum Type {
//         // DB constraint violation
//         DUPLICATE_KEY,
// 
//         // Entity provided is not valid
//         ENTITY_ERROR,
// 
//         // Unknown or implementation error
//         GENERAL_ERROR,
// 
//         // params supplied via HTTP are invalid
//         PARAMS_ERROR,
// 
//         // Service query contains errors
//         QUERY_ERROR
//     }
// 
//     // default type
//     private Type type = Type.GENERAL_ERROR;
// 
//     public RestDslException(String message) {
//         super(message);
//     }
// 
//     public RestDslException(String message, Type type) {
//         super(message);
//         this.type = type;
//     }
// 
//     public RestDslException(String message, Throwable cause, Type type) {
//         super(message, cause);
//         this.type = type;
//     }
// 
//     public Type getType() {
//         return type;
//     }
// 
// }
// 
// Path: restler-core/src/main/java/net/researchgate/restdsl/types/TypeInfoUtil.java
// public class TypeInfoUtil {
//     private static final Logger LOGGER = LoggerFactory.getLogger(TypeInfoUtil.class);
// 
//     public static final Mapper MAPPER = new Morphia().getMapper();
// 
//     private static Map<Class, TypeConverter<?>> converters = new HashMap<>();
// 
// 
//     public static void addConverter(TypeConverter<?> converter) {
//         if (converters.containsKey(converter.getType())) {
//             LOGGER.warn("Converter for class " + converter.getType().getName() + " has been already registered");
//         }
//         converters.put(converter.getType(), converter);
//     }
// 
// 
//     //TODO: converters via annotations
//     @SuppressWarnings("unchecked")
//     // fieldName and parentClazz are needed for potential reflection to get serde info from a field
//     public static <K> K getValue(String strVal, String fieldName, Class<K> clazz, Class<?> parentClazz) throws RestDslException {
//         try {
//             ServiceQueryReservedValue reservedValue = ServiceQueryReservedValue.fromString(strVal);
//             if (reservedValue != null) {
//                 if (reservedValue == ServiceQueryReservedValue.NULL) {
//                     return null;
//                 }
//                 return (K) reservedValue;
//             }
//             if (converters.containsKey(clazz)) {
//                 return (K) converters.get(clazz).deserialize(strVal);
//             }
// 
//             if (clazz == String.class) {
//                 return (K) strVal;
//             } else if (clazz == Long.class || clazz == long.class) {
//                 return (K) Long.valueOf(strVal, 10);
//             } else if (clazz == Integer.class || clazz == int.class) {
//                 return (K) Integer.valueOf(strVal, 10);
//             } else if (clazz == ObjectId.class) {
//                 return (K) new ObjectId(strVal);
//             } else if (clazz == Boolean.class || clazz == boolean.class) {
//                 return (K) Boolean.valueOf(strVal);
//             } else if (clazz.isEnum()) {
//                 Class c = clazz;
//                 Converter<String, K> converter = Enums.stringConverter(c);
//                 return converter.convert(strVal);
//             } else if (clazz == Date.class) {
//                 return (K) new Date(Long.valueOf(strVal, 10));
//             }
//         } catch (Exception e) {
//             throw new RestDslException("Cannot convert '" + strVal + "' to object of class " + clazz.getName(), e, RestDslException.Type.PARAMS_ERROR);
//         }
//         throw new RestDslException("Unsupported type " + clazz.getName() + " for value '" + strVal + "'", RestDslException.Type.PARAMS_ERROR);
//     }
// 
// 
//     //TODO: get rid of Pair
//     public static Pair<Class<?>, Class<?>> getFieldExpressionClazz(Class<?> cl, String fieldExpression) throws RestDslException {
//         return getFieldExpressionClazz(cl, null, fieldExpression, Splitter.on('.').splitToList(fieldExpression), 0);
//     }
// 
//     private static Pair<Class<?>, Class<?>> getFieldExpressionClazz(Class<?> cl, Class<?> prevClazz, String fieldExpression, List<String> fields, int ptr) throws RestDslException {
//         if (ptr >= fields.size()) {
//             return Pair.of(cl, prevClazz);
//         }
//         String fieldName = fields.get(ptr);
// 
//         //TODO: cache mapped info
//         MappedClass mc = MAPPER.getMappedClass(cl);
//         MappedField nestedField = mc.getMappedFieldByJavaField(fieldName);
//         if (nestedField == null) {
//             throw new RestDslException("Cannot find field " + fieldExpression, RestDslException.Type.PARAMS_ERROR);
//         }
//         Class<?> nestedClazz = nestedField.getType();
//         //TODO: better type checking
//         if (nestedClazz.isAssignableFrom(List.class)) {
//             Type subType = nestedField.getSubType();
//             return getFieldExpressionClazz((Class<?>) subType, cl, fieldExpression, fields, ptr + 1);
//         } else {
//             return getFieldExpressionClazz(nestedClazz, cl, fieldExpression, fields, ptr + 1);
//         }
//     }
// }


// Path: restler-core/src/test/java/net/researchgate/restdsl/util/TypeInfoUtilTest.java
import net.researchgate.restdsl.entities.Account;
import net.researchgate.restdsl.exceptions.RestDslException;
import net.researchgate.restdsl.types.TypeInfoUtil;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;

package net.researchgate.restdsl.util;



/**
 * Testing conversion methods
 */
public class TypeInfoUtilTest {

    @Test
    public void testSimple() {
        assertEquals(123L, (Object) TypeInfoUtil.getValue("123", "id", Long.class, Account.class));

        try {
            TypeInfoUtil.getValue("123X", "id", Long.class, Account.class);