class RowTypeInfo extends TupleTypeInfoBase<Row> {

	@Override
	public <X> TypeInformation<X> getTypeAt(String fieldExpression) {
		Matcher matcher = PATTERN_NESTED_FIELDS.matcher(fieldExpression);
		if (!matcher.matches()) {
			if (fieldExpression.equals(ExpressionKeys.SELECT_ALL_CHAR) ||
				fieldExpression.equals(ExpressionKeys.SELECT_ALL_CHAR_SCALA)) {
				throw new InvalidFieldReferenceException("Wildcard expressions are not allowed here.");
			} else {
				throw new InvalidFieldReferenceException("Invalid format of Row field expression \""+fieldExpression+"\".");
			}
		}

		String field = matcher.group(1);

		Matcher intFieldMatcher = PATTERN_INT_FIELD.matcher(field);
		int fieldIndex;
		if (intFieldMatcher.matches()) {
			// field expression is an integer
			fieldIndex = Integer.valueOf(field);
		} else {
			fieldIndex = this.getFieldIndex(field);
		}
		// fetch the field type will throw exception if the index is illegal
		TypeInformation<X> fieldType = this.getTypeAt(fieldIndex);

		String tail = matcher.group(3);
		if (tail == null) {
			// found the type
			return fieldType;
		} else {
			if (fieldType instanceof CompositeType) {
				return ((CompositeType<?>) fieldType).getTypeAt(tail);
			} else {
				throw new InvalidFieldReferenceException(
					"Nested field expression \""+ tail + "\" not possible on atomic type "+fieldType+".");
			}
		}
	}

	public  RowTypeInfo(TypeInformation<?>... types);
	public  RowTypeInfo(TypeInformation<?>[] types, String[] fieldNames);

}