code: public static Object parseValue(Object value) {
  		if (value == null) {
  			return null;
  		}
  		if (value instanceof Double) {
  			return new BigDecimal((Double) value);
  		} else if (value instanceof Long) {
  			return new BigDecimal((Long) value);
  		} else if (value instanceof Integer) {
  			return new BigDecimal((Integer) value);
  		} else if (value instanceof Float) {
  			return new BigDecimal((Float) value);
  		} else if (value instanceof Short) {
  			return new BigDecimal((Short) value);
  		} else if (value instanceof String) {
  			return ((String) value).trim();
  		} else if (value instanceof Apptentive.Version) {
  			return value;
  		} else if (value instanceof Apptentive.DateTime) {
  			return value;
  		} else if (value instanceof JSONObject) {
  			JSONObject jsonObject = (JSONObject) value;
  			String typeName = jsonObject.optString(KEY_COMPLEX_TYPE);
  			if (typeName != null) {
  				try {
  					if (Apptentive.Version.TYPE.equals(typeName)) {
  						return new Apptentive.Version(jsonObject);
  					} else if (Apptentive.DateTime.TYPE.equals(typeName)) {
  						return new Apptentive.DateTime(jsonObject);
  					} else {
  						throw new RuntimeException(String.format("Error parsing complex parameter with unrecognized name: \"%s\"", typeName));
  					}
  				} catch (JSONException e) {
  					throw new RuntimeException(String.format("Error parsing complex parameter: %s", Util.classToString(value)), e);
  				}
  			} else {
  				throw new RuntimeException(String.format("Error: Complex type parameter missing \"%s\".", KEY_COMPLEX_TYPE));
  			}
  		}
  		// All other values, such as Boolean and String should be returned unaltered.
  		return value;
  	}
docs: Constructs complex types values from the JSONObjects that represent them. Turns all Numbers
  into BigDecimal for easier comparison. All fields and parameters must be run through this
  method.
  
  @param value
  @return null if value is a JSONObject, but not a complex type.