### Question:
ELUtils { public static TypeDescriptor getTypeDescriptor(ValueExpression valueExpression, ELContext elContext) { Assert.notNull(valueExpression, "ValueExpression must not be null"); Assert.notNull(elContext, "ELContext must not be null"); TrackedELContext trackedContext = new TrackedELContext(elContext); Class<?> type = valueExpression.getType(trackedContext); if (type == null) { return null; } TypeDescriptor typeDescriptor = TypeDescriptor.valueOf(type); if (typeDescriptor.isCollection() || typeDescriptor.isMap()) { if (trackedContext.hasValues()) { try { Property property = getProperty(trackedContext); if (property != null) { typeDescriptor = new TypeDescriptor(property); } } catch (Exception e) { } } } return typeDescriptor; }  static TypeDescriptor getTypeDescriptor(ValueExpression valueExpression, ELContext elContext); static Property getProperty(ValueExpression valueExpression, ELContext elContext);  }### Answer:
@Test public void shouldGetTypeDescriptorForSimpleType() throws Exception { ValueExpression valueExpression = newValueExpression("integer", Object.class); TypeDescriptor typeDescriptor = ELUtils.getTypeDescriptor(valueExpression, this.context); assertThat(typeDescriptor.getType(), is(equalTo((Class) Integer.class))); }
@Test public void shouldGetTypeDescriptorForArray() throws Exception { ValueExpression valueExpression = newValueExpression("arrayOfString", Object.class); TypeDescriptor typeDescriptor = ELUtils.getTypeDescriptor(valueExpression, this.context); assertThat(typeDescriptor.isArray(), is(true)); assertThat(typeDescriptor.getElementTypeDescriptor(), is(TypeDescriptor.valueOf(String.class))); }
@Test public void shouldGetTypeDescriptorForCollectionWithGeneric() throws Exception { ValueExpression valueExpression = newValueExpression("setOfLong", Object.class); TypeDescriptor typeDescriptor = ELUtils.getTypeDescriptor(valueExpression, this.context); assertThat(typeDescriptor.getType(), is(equalTo((Class) Set.class))); assertThat(typeDescriptor.isCollection(), is(true)); assertThat(typeDescriptor.getElementTypeDescriptor(), is(TypeDescriptor.valueOf(Long.class))); }
@Test public void shouldGetTypeDescriptorForMapWithGenerics() throws Exception { ValueExpression valueExpression = newValueExpression("mapOfStringInteger", Object.class); TypeDescriptor typeDescriptor = ELUtils.getTypeDescriptor(valueExpression, this.context); assertThat(typeDescriptor.getType(), is(equalTo((Class) Map.class))); assertThat(typeDescriptor.isMap(), is(true)); assertThat(typeDescriptor.getMapKeyTypeDescriptor(), is(TypeDescriptor.valueOf(String.class))); assertThat(typeDescriptor.getMapValueTypeDescriptor(), is(TypeDescriptor.valueOf(Integer.class))); }
@Test public void shouldGetTypeDescriptorForNested() throws Exception { ValueExpression valueExpression = newValueExpression("nested.collectionOfInteger", Object.class); TypeDescriptor typeDescriptor = ELUtils.getTypeDescriptor(valueExpression, this.context); assertThat(typeDescriptor.getType(), is(equalTo((Class) Collection.class))); assertThat(typeDescriptor.isCollection(), is(true)); assertThat(typeDescriptor.getElementTypeDescriptor(), is(TypeDescriptor.valueOf(Integer.class))); }