public static DataSchema buildSkeletonSchema(DataSchema schema) throws CloneNotSupportedException
  {
    switch (schema.getType())
    {
      case RECORD:
        RecordDataSchema newRecordSchema = new RecordDataSchema(new Name(((RecordDataSchema) schema).getFullName()),
                                         RecordDataSchema.RecordType.RECORD);
        RecordDataSchema originalRecordSchema = (RecordDataSchema) schema;
        if (originalRecordSchema.getAliases() != null)
        {
          newRecordSchema.setAliases(originalRecordSchema.getAliases());
        }
        if (originalRecordSchema.getDoc() != null)
        {
          newRecordSchema.setDoc(originalRecordSchema.getDoc());
        }
        if (originalRecordSchema.getProperties() != null)
        {
          newRecordSchema.setProperties(originalRecordSchema.getProperties());
        }
        return newRecordSchema;
      case UNION:
        UnionDataSchema newUnionDataSchema = new UnionDataSchema();
        UnionDataSchema unionDataSchema = (UnionDataSchema) schema;
        if (unionDataSchema.getProperties() != null)
        {
          newUnionDataSchema.setProperties(unionDataSchema.getProperties());
        }
        return newUnionDataSchema;
      case TYPEREF:
        TyperefDataSchema originalTypeRefSchema = (TyperefDataSchema) schema;
        TyperefDataSchema newTypeRefSchema = new TyperefDataSchema(new Name(originalTypeRefSchema.getFullName()));
        if (originalTypeRefSchema.getProperties() != null)
        {
          newTypeRefSchema.setProperties(originalTypeRefSchema.getProperties());
        }
        if (originalTypeRefSchema.getDoc() != null)
        {
          newTypeRefSchema.setDoc(originalTypeRefSchema.getDoc());
        }
        if (originalTypeRefSchema.getAliases() != null)
        {
          newTypeRefSchema.setAliases(originalTypeRefSchema.getAliases());
        }
        return newTypeRefSchema;
      case ARRAY:
        ArrayDataSchema originalArrayDataSchema = (ArrayDataSchema) schema;
        //Set null item types for this skeleton
        ArrayDataSchema newArrayDataSchema = new ArrayDataSchema(DataSchemaConstants.NULL_DATA_SCHEMA);
        if (originalArrayDataSchema.getProperties() != null)
        {
          newArrayDataSchema.setProperties(originalArrayDataSchema.getProperties());
        }
        return newArrayDataSchema;
      case MAP:
        MapDataSchema originalMapDataSchema = (MapDataSchema) schema;
        //Set null value types for this skeleton
        MapDataSchema newMapDataSchema = new MapDataSchema(DataSchemaConstants.NULL_DATA_SCHEMA);
        if (originalMapDataSchema.getProperties() != null)
        {
          newMapDataSchema.setProperties(originalMapDataSchema.getProperties());
        }
        return newMapDataSchema;
      case FIXED:
      case ENUM:
      default:
        // Primitive types, FIXED, ENUM: using schema's clone method
        return schema.clone();
    }
  }
@Test
  public void testBuildSkeletonSchema() throws Exception
  {
    DataSchema oldSchema = null;
    RecordDataSchema fooSchema = (RecordDataSchema) TestUtil.dataSchemaFromString(fooSchemaText);
    // Test Record
    RecordDataSchema newRecordSchema = (RecordDataSchema) CopySchemaUtil.buildSkeletonSchema(fooSchema);
    assert((newRecordSchema.getFields().size() == 0) && Objects.equals(newRecordSchema.getDoc(), fooSchema.getDoc())
           && Objects.equals(newRecordSchema.getProperties(), fooSchema.getProperties())
           && Objects.equals(newRecordSchema.getAliases(), fooSchema.getAliases()));
    // Test TypeRef
    oldSchema = fooSchema.getField("typeRefField").getType();
    TyperefDataSchema newTypeRefDataSchema = (TyperefDataSchema) CopySchemaUtil.buildSkeletonSchema(oldSchema);
    assert( Objects.equals(newTypeRefDataSchema.getDoc(), ((TyperefDataSchema) oldSchema).getDoc())
           && Objects.equals(newTypeRefDataSchema.getProperties(), oldSchema.getProperties())
           && Objects.equals(newTypeRefDataSchema.getAliases(), ((TyperefDataSchema)oldSchema).getAliases()));
    // Test Union
    oldSchema = fooSchema.getField("unionField").getType();
    UnionDataSchema newUnionDataSchema = (UnionDataSchema) CopySchemaUtil.buildSkeletonSchema(oldSchema);
    assert(newUnionDataSchema.getMembers().size() == 0 && Objects.equals(newUnionDataSchema.getProperties(), oldSchema.getProperties()));
    // Test map
    oldSchema = fooSchema.getField("mapField").getType();
    MapDataSchema mapDataSchema = (MapDataSchema) CopySchemaUtil.buildSkeletonSchema(oldSchema);
    assert (Objects.equals(mapDataSchema.getProperties(), oldSchema.getProperties()) &&
            Objects.equals(mapDataSchema.getValues(), DataSchemaConstants.NULL_DATA_SCHEMA));
    // Test array
    oldSchema = fooSchema.getField("arrayField").getType();
    ArrayDataSchema arrayDataSchema = (ArrayDataSchema) CopySchemaUtil.buildSkeletonSchema(oldSchema);
    assert (Objects.equals(arrayDataSchema.getProperties(), oldSchema.getProperties()) &&
            Objects.equals(arrayDataSchema.getItems(), DataSchemaConstants.NULL_DATA_SCHEMA));
    // Test ENUM
    oldSchema = fooSchema.getField("enumField").getType();
    EnumDataSchema enumDataSchema = (EnumDataSchema) CopySchemaUtil.buildSkeletonSchema(oldSchema);
    Assert.assertEquals(enumDataSchema, oldSchema);
    // Test FIXED
    oldSchema = fooSchema.getField("fixedField").getType();
    FixedDataSchema fixedDataSchema = (FixedDataSchema) CopySchemaUtil.buildSkeletonSchema(oldSchema);
    Assert.assertEquals(fixedDataSchema, oldSchema);
    // Test primitive
    oldSchema = fooSchema.getField("intField").getType();
    PrimitiveDataSchema primitiveDataSchema = (PrimitiveDataSchema) CopySchemaUtil.buildSkeletonSchema(oldSchema);
    Assert.assertEquals(primitiveDataSchema, oldSchema);

  }