@SuppressWarnings("unchecked")
  public static SelType box(Object o) {
    if (o == null) { // returned null from a method, representing void or object
      return SelType.NULL;
    }
    SelTypes type = fromClazzToSelType(o.getClass());
    switch (type) {
      case STRING:
        return SelString.of((String) o);
      case LONG:
        return SelLong.of(((Number) o).longValue());
      case DOUBLE:
        return SelDouble.of(((Number) o).doubleValue());
      case BOOLEAN:
        return SelBoolean.of((Boolean) o);
      case STRING_ARRAY:
      case LONG_ARRAY:
      case DOUBLE_ARRAY:
      case BOOLEAN_ARRAY:
        return SelArray.of(o, type);
      case MAP:
        return SelMap.of((Map<String, Object>) o);
      case DATETIME:
        return SelJodaDateTime.of((DateTime) o);
      case DATETIME_PROPERTY:
        return SelJodaDateTimeProperty.of((DateTime.Property) o);
    }
    throw new UnsupportedOperationException(
        "Not support to box an object " + o + " for type " + type.name());
  }
@Test
  public void testBox() {
    Object[] testObjects =
        new Object[] {
          null,
          "abc",
          1,
          1L,
          true,
          new String[] {"foo", "bar"},
          new Long[] {1L, 2L},
          new long[] {1L, 2L},
          new Integer[] {3, 4},
          new int[] {5, 6, 7},
          new Boolean[] {true, false},
          new boolean[] {},
          new HashMap(),
          new DateTime(DateTimeZone.UTC),
          new DateTime(DateTimeZone.UTC).dayOfWeek()
        };
    String[] expectedResults =
        new String[] {
          "NULL: NULL",
          "STRING: abc",
          "LONG: 1",
          "LONG: 1",
          "BOOLEAN: true",
          "STRING_ARRAY: [foo, bar]",
          "LONG_ARRAY: [1, 2]",
          "LONG_ARRAY: [1, 2]",
          "LONG_ARRAY: [3, 4]",
          "LONG_ARRAY: [5, 6, 7]",
          "BOOLEAN_ARRAY: [true, false]",
          "BOOLEAN_ARRAY: []",
          "MAP: {}",
          "DATETIME: 1970-01-01T00:00:12.345Z",
          "DATETIME_PROPERTY: Property[dayOfWeek]"
        };

    for (int i = 0; i < testObjects.length; ++i) {
      SelType res = SelTypeUtil.box(testObjects[i]);
      assertEquals(expectedResults[i], res.type() + ": " + res.toString());
    }
  }