@Override
 public RType getSubscriptionType(List<RExpression> indices, boolean isSingleBracket) {
   if (indices.isEmpty()) {
     return this;
   }
   if (indices.size() > 1) {
     return RUnknownType.INSTANCE;
   }
   RExpression index = indices.get(0);
   RType type = RUnknownType.INSTANCE;
   String indexName = null;
   if (index instanceof RStringLiteralExpression) {
     String quoted = index.getText();
     indexName = quoted.substring(1, quoted.length() - 1);
     type = getFieldType(indexName);
   }
   if (index instanceof RNumericLiteralExpression) {
     try {
       int i = Integer.parseInt(index.getText());
       TypeDescriptor descriptor = getFieldDescriptor(i - 1);
       indexName = descriptor.myName;
       type = descriptor.myType;
     } catch (NumberFormatException e) {
       // Do nothing
     }
   }
   if (!RNullType.class.isInstance(type)
       && !RUnknownType.class.isInstance(type)
       && isSingleBracket) {
     RListType listType = new RListType();
     listType.addField(indexName, type);
     type = listType;
   }
   return type;
 }
 // handles assignment to subscription expression
 @Override
 public RType afterSubscriptionType(
     List<RExpression> indices, RType valueType, boolean isSingleBracket) {
   if (indices.isEmpty()) {
     return this;
   }
   if (indices.size() > 1) {
     return RUnknownType.INSTANCE;
   }
   if (isSingleBracket && valueType instanceof RListType) {
     RListType list = (RListType) valueType;
     if (!list.myPrecise) {
       return RUnknownType.INSTANCE;
     }
     if (list.myPositionalTypes.isEmpty()) {
       return RUnknownType.INSTANCE;
     }
     valueType = list.myPositionalTypes.get(0).myType;
   }
   RExpression index = indices.get(0);
   RListType resultType = new RListType(this);
   if (index instanceof RStringLiteralExpression) {
     String quoted = index.getText();
     String indexName = quoted.substring(1, quoted.length() - 1);
     if (valueType instanceof RNullType) {
       resultType.removeField(indexName);
     } else {
       resultType.addField(indexName, valueType);
     }
   }
   if (index instanceof RNumericLiteralExpression) {
     try {
       int i = Integer.parseInt(index.getText());
       if (valueType instanceof RNullType) {
         resultType.removeField(i - 1);
       } else {
         resultType.addField(i - 1, valueType);
       }
     } catch (NumberFormatException e) {
       // do nothing
     }
   }
   return resultType;
 }
 @Override
 public RType afterMemberType(String tag, RType valueType) {
   RListType clone = clone();
   if (valueType instanceof RNullType) {
     clone.removeField(tag);
   } else {
     clone.addField(tag, valueType);
   }
   return clone;
 }