@SuppressWarnings("unchecked")
  @Override
  public Table createMappedForm(PersistentEntity entity) {
    Table table = super.createMappedForm(entity);
    CassandraPersistentEntity cassandraPersistentEntity = (CassandraPersistentEntity) entity;
    // read tableOptions
    ClassPropertyFetcher cpf = ClassPropertyFetcher.forClass(entity.getJavaClass());
    final Closure value = cpf.getStaticPropertyValue(TABLE_PROPERTIES, Closure.class);
    if (value != null) {
      MapConfigurationBuilder builder = new MapConfigurationBuilder();
      try {
        builder.evaluate(value);
      } catch (Exception e) {
        throw new IllegalMappingException(
            String.format("Error reading %s : %s", TABLE_PROPERTIES, e.toString()));
      }
      table.setTableProperties(builder.getProperties());
    }

    if (table.getKeyspace() == null) {
      table.setKeyspace(keyspace);
    }

    // additional static mapping block handling
    Map<String, Column> properties = entityToPropertyMap.get(entity);
    Object version = properties.get(MappingConfigurationBuilder.VERSION_KEY);
    if (version instanceof Boolean) {
      cassandraPersistentEntity.setVersion((Boolean) version);
    }

    Column idProperty = properties.get(IDENTITY_PROPERTY);
    Iterator<Entry<String, Column>> propertyIterator = properties.entrySet().iterator();

    while (propertyIterator.hasNext()) {
      Entry<String, Column> entry = propertyIterator.next();
      if (entry.getValue() instanceof Column) {
        String name = entry.getKey();
        Column column = entry.getValue();
        if (idProperty != null
            && idProperty.getName() != null
            && idProperty.getName().equals(name)) {
          // remove extra column created if id property in constraints block, as it conflicts with
          // the column created in mapping block.
          // constraints will be handled elsewhere in GORM
          propertyIterator.remove();
          continue;
        }

        if (column.getName() == null) {
          column.setName(name);
        }
        table.addColumn(column);
      }
    }

    return table;
  }
  @Override
  public CreateTableSpecification getCreateTableSpecificationFor(
      CassandraPersistentEntity<?> entity) {

    Assert.notNull(entity);

    final CreateTableSpecification spec = new CreateTableSpecification();

    spec.name(entity.getTableName());

    entity.doWithProperties(
        new PropertyHandler<CassandraPersistentProperty>() {

          @Override
          public void doWithPersistentProperty(CassandraPersistentProperty prop) {

            if (prop.isCompositePrimaryKey()) {

              CassandraPersistentEntity<?> pkEntity = getPersistentEntity(prop.getRawType());

              pkEntity.doWithProperties(
                  new PropertyHandler<CassandraPersistentProperty>() {

                    @Override
                    public void doWithPersistentProperty(CassandraPersistentProperty pkProp) {

                      if (pkProp.isPartitionKeyColumn()) {
                        spec.partitionKeyColumn(pkProp.getColumnName(), pkProp.getDataType());
                      } else {
                        spec.clusteredKeyColumn(
                            pkProp.getColumnName(),
                            pkProp.getDataType(),
                            pkProp.getPrimaryKeyOrdering());
                      }
                    }
                  });

            } else {

              if (prop.isIdProperty()) {
                spec.partitionKeyColumn(prop.getColumnName(), prop.getDataType());
              } else {
                spec.column(prop.getColumnName(), prop.getDataType());
              }
            }
          }
        });

    if (spec.getPartitionKeyColumns().isEmpty()) {
      throw new MappingException(
          "no partition key columns found in the entity " + entity.getType());
    }

    return spec;
  }