@SuppressWarnings("unchecked")
  private void writeFeedTypeDetailsRecordType(
      IARecordBuilder recordBuilder, Feed feed, ArrayBackedValueStorage fieldValue)
      throws HyracksDataException {

    switch (feed.getFeedType()) {
      case PRIMARY:
        {
          PrimaryFeed primaryFeed = (PrimaryFeed) feed;

          IARecordBuilder primaryDetailsRecordBuilder = new RecordBuilder();
          OrderedListBuilder listBuilder = new OrderedListBuilder();
          ArrayBackedValueStorage primaryRecordfieldValue = new ArrayBackedValueStorage();
          ArrayBackedValueStorage primaryRecordItemValue = new ArrayBackedValueStorage();
          primaryDetailsRecordBuilder.reset(MetadataRecordTypes.PRIMARY_FEED_DETAILS_RECORDTYPE);

          AMutableString aString = new AMutableString("");
          ISerializerDeserializer<AString> stringSerde =
              AqlSerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(
                  BuiltinType.ASTRING);

          // write field 0
          fieldValue.reset();
          aString.setValue(primaryFeed.getAdaptorName());
          stringSerde.serialize(aString, primaryRecordfieldValue.getDataOutput());
          primaryDetailsRecordBuilder.addField(
              MetadataRecordTypes.FEED_ARECORD_PRIMARY_FIELD_DETAILS_ADAPTOR_NAME_FIELD_INDEX,
              primaryRecordfieldValue);

          // write field 1
          listBuilder.reset(
              (AUnorderedListType)
                  MetadataRecordTypes.PRIMARY_FEED_DETAILS_RECORDTYPE
                      .getFieldTypes()[
                      MetadataRecordTypes
                          .FEED_ARECORD_PRIMARY_FIELD_DETAILS_ADAPTOR_CONFIGURATION_FIELD_INDEX]);
          for (Map.Entry<String, String> property :
              primaryFeed.getAdaptorConfiguration().entrySet()) {
            String name = property.getKey();
            String value = property.getValue();
            primaryRecordItemValue.reset();
            writePropertyTypeRecord(name, value, primaryRecordItemValue.getDataOutput());
            listBuilder.addItem(primaryRecordItemValue);
          }
          primaryRecordfieldValue.reset();
          listBuilder.write(primaryRecordfieldValue.getDataOutput(), true);
          primaryDetailsRecordBuilder.addField(
              MetadataRecordTypes
                  .FEED_ARECORD_PRIMARY_FIELD_DETAILS_ADAPTOR_CONFIGURATION_FIELD_INDEX,
              primaryRecordfieldValue);

          try {
            primaryDetailsRecordBuilder.write(fieldValue.getDataOutput(), true);
          } catch (IOException | AsterixException e) {
            throw new HyracksDataException(e);
          }

          recordBuilder.addField(
              MetadataRecordTypes.FEED_ARECORD_PRIMARY_TYPE_DETAILS_FIELD_INDEX, fieldValue);
        }
        break;

      case SECONDARY:
        SecondaryFeed secondaryFeed = (SecondaryFeed) feed;

        IARecordBuilder secondaryDetailsRecordBuilder = new RecordBuilder();
        ArrayBackedValueStorage secondaryFieldValue = new ArrayBackedValueStorage();
        secondaryDetailsRecordBuilder.reset(MetadataRecordTypes.SECONDARY_FEED_DETAILS_RECORDTYPE);

        // write field 0
        fieldValue.reset();
        aString.setValue(secondaryFeed.getSourceFeedName());
        stringSerde.serialize(aString, secondaryFieldValue.getDataOutput());
        secondaryDetailsRecordBuilder.addField(
            MetadataRecordTypes.FEED_ARECORD_SECONDARY_FIELD_DETAILS_SOURCE_FEED_NAME_FIELD_INDEX,
            secondaryFieldValue);

        try {
          secondaryDetailsRecordBuilder.write(fieldValue.getDataOutput(), true);
        } catch (IOException | AsterixException e) {
          throw new HyracksDataException(e);
        }
        recordBuilder.addField(
            MetadataRecordTypes.FEED_ARECORD_SECONDARY_TYPE_DETAILS_FIELD_INDEX, fieldValue);
        break;
    }
  }
  @Override
  public ITupleReference getTupleFromMetadataEntity(Feed feed)
      throws IOException, MetadataException {
    // write the key in the first two fields of the tuple
    tupleBuilder.reset();
    aString.setValue(feed.getDataverseName());
    stringSerde.serialize(aString, tupleBuilder.getDataOutput());
    tupleBuilder.addFieldEndOffset();

    aString.setValue(feed.getFeedName());
    stringSerde.serialize(aString, tupleBuilder.getDataOutput());
    tupleBuilder.addFieldEndOffset();

    recordBuilder.reset(MetadataRecordTypes.FEED_RECORDTYPE);

    // write field 0
    fieldValue.reset();
    aString.setValue(feed.getDataverseName());
    stringSerde.serialize(aString, fieldValue.getDataOutput());
    recordBuilder.addField(MetadataRecordTypes.FEED_ARECORD_DATAVERSE_NAME_FIELD_INDEX, fieldValue);

    // write field 1
    fieldValue.reset();
    aString.setValue(feed.getFeedName());
    stringSerde.serialize(aString, fieldValue.getDataOutput());
    recordBuilder.addField(MetadataRecordTypes.FEED_ARECORD_FEED_NAME_FIELD_INDEX, fieldValue);

    // write field 2
    fieldValue.reset();
    if (feed.getAppliedFunction() != null) {
      aString.setValue(feed.getAppliedFunction().getName());
      stringSerde.serialize(aString, fieldValue.getDataOutput());
      recordBuilder.addField(MetadataRecordTypes.FEED_ARECORD_FUNCTION_FIELD_INDEX, fieldValue);
    }

    // write field 3
    fieldValue.reset();
    aString.setValue(feed.getFeedType().name().toUpperCase());
    stringSerde.serialize(aString, fieldValue.getDataOutput());
    recordBuilder.addField(MetadataRecordTypes.FEED_ARECORD_FEED_TYPE_FIELD_INDEX, fieldValue);

    // write field 4/5
    fieldValue.reset();
    writeFeedTypeDetailsRecordType(recordBuilder, feed, fieldValue);

    // write field 6
    fieldValue.reset();
    aString.setValue(Calendar.getInstance().getTime().toString());
    stringSerde.serialize(aString, fieldValue.getDataOutput());
    recordBuilder.addField(MetadataRecordTypes.FEED_ARECORD_TIMESTAMP_FIELD_INDEX, fieldValue);

    // write record
    try {
      recordBuilder.write(tupleBuilder.getDataOutput(), true);
    } catch (AsterixException e) {
      throw new MetadataException(e);
    }
    tupleBuilder.addFieldEndOffset();

    tuple.reset(tupleBuilder.getFieldEndOffsets(), tupleBuilder.getByteArray());
    return tuple;
  }