code: private void processCustomFieldValues()
     {
        byte[] data = m_projectProps.getByteArray(Props.TASK_FIELD_ATTRIBUTES);
        if (data != null)
        {
           int index = 0;
           int offset = 0;
           // First the length
           int length = MPPUtility.getInt(data, offset);
           offset += 4;
           // Then the number of custom value lists
           int numberOfValueLists = MPPUtility.getInt(data, offset);
           offset += 4;
  
           // Then the value lists themselves
           FieldType field;
           int valueListOffset = 0;
           while (index < numberOfValueLists && offset < length)
           {
              // Each item consists of the Field ID (4 bytes) and the offset to the value list (4 bytes)
  
              // Get the Field
              field = FieldTypeHelper.getInstance(MPPUtility.getInt(data, offset));
              offset += 4;
  
              // Get the value list offset
              valueListOffset = MPPUtility.getInt(data, offset);
              offset += 4;
              // Read the value list itself
              if (valueListOffset < data.length)
              {
                 int tempOffset = valueListOffset;
                 tempOffset += 8;
                 // Get the data offset
                 int dataOffset = MPPUtility.getInt(data, tempOffset) + valueListOffset;
                 tempOffset += 4;
                 // Get the end of the data offset
                 int endDataOffset = MPPUtility.getInt(data, tempOffset) + valueListOffset;
                 tempOffset += 4;
                 // Get the end of the description
                 int endDescriptionOffset = MPPUtility.getInt(data, tempOffset) + valueListOffset;
  
                 // Get the values themselves
                 int valuesLength = endDataOffset - dataOffset;
                 byte[] values = new byte[valuesLength];
                 MPPUtility.getByteArray(data, dataOffset, valuesLength, values, 0);
  
                 // Get the descriptions
                 int descriptionsLength = endDescriptionOffset - endDataOffset;
                 byte[] descriptions = new byte[descriptionsLength];
                 MPPUtility.getByteArray(data, endDataOffset, descriptionsLength, descriptions, 0);
  
                 populateContainer(field, values, descriptions);
              }
              index++;
           }
        }
     }
docs: Reads non outline code custom field values and populates container.