public BoundStatementWrapper bindForUpdate(
      PersistentStateHolder context, PreparedStatement ps, List<PropertyMeta> pms) {
    EntityMeta entityMeta = context.getEntityMeta();
    Object entity = context.getEntity();

    log.trace(
        "Bind prepared statement {} for properties {} update of entity {}",
        ps.getQueryString(),
        pms,
        entity);

    ConsistencyLevel consistencyLevel = overrider.getWriteLevel(context);

    List<Object> values = new ArrayList<>();

    final int staticColumnsCount =
        FluentIterable.from(pms).filter(PropertyMeta.STATIC_COLUMN_FILTER).size();
    final boolean onlyStaticColumns = staticColumnsCount > 0 && pms.size() == staticColumnsCount;

    values.addAll(fetchTTLAndTimestampValues(context));
    values.addAll(fetchPropertiesValues(pms, entity));
    values.addAll(fetchPrimaryKeyValues(entityMeta, entity, onlyStaticColumns));
    values.addAll(fetchCASConditionsValues(context, entityMeta));
    BoundStatement bs = ps.bind(values.toArray());

    return new BoundStatementWrapper(
        context.getEntityClass(),
        bs,
        values.toArray(),
        getCQLLevel(consistencyLevel),
        context.getCASResultListener(),
        context.getSerialConsistencyLevel());
  }
  public BoundStatementWrapper bindForInsert(
      PersistentStateHolder context, PreparedStatement ps, List<PropertyMeta> pms) {

    EntityMeta entityMeta = context.getEntityMeta();
    Object entity = context.getEntity();

    log.trace("Bind prepared statement {} for insert of entity {}", ps.getQueryString(), entity);

    ConsistencyLevel consistencyLevel = overrider.getWriteLevel(context);

    List<Object> values = new ArrayList<>();
    values.addAll(fetchPrimaryKeyValues(entityMeta, entity, false));
    values.addAll(fetchPropertiesValues(pms, entity));
    values.addAll(fetchTTLAndTimestampValues(context));

    BoundStatement bs = ps.bind(values.toArray());
    return new BoundStatementWrapper(
        context.getEntityClass(),
        bs,
        values.toArray(),
        getCQLLevel(consistencyLevel),
        context.getCASResultListener(),
        context.getSerialConsistencyLevel());
  }
  public BoundStatementWrapper bindForCollectionAndMapUpdate(
      PersistentStateHolder context, PreparedStatement ps, DirtyCheckChangeSet changeSet) {
    EntityMeta entityMeta = context.getEntityMeta();
    Object entity = context.getEntity();

    log.trace(
        "Bind prepared statement {} for collection/map update of entity {}",
        ps.getQueryString(),
        entity);

    ConsistencyLevel consistencyLevel = overrider.getWriteLevel(context);

    List<Object> values = new ArrayList<>();
    final CollectionAndMapChangeType changeType = changeSet.getChangeType();

    values.addAll(fetchTTLAndTimestampValues(context));

    switch (changeType) {
      case ASSIGN_VALUE_TO_LIST:
        values.add(changeSet.getEncodedListChanges());
        break;
      case ASSIGN_VALUE_TO_SET:
        values.add(changeSet.getEncodedSetChanges());
        break;
      case ASSIGN_VALUE_TO_MAP:
        values.add(changeSet.getEncodedMapChanges());
        break;
      case REMOVE_COLLECTION_OR_MAP:
        values.add(null);
        break;
      case ADD_TO_SET:
      case REMOVE_FROM_SET:
        values.add(changeSet.getEncodedSetChanges());
        break;
      case APPEND_TO_LIST:
      case PREPEND_TO_LIST:
      case REMOVE_FROM_LIST:
        values.add(changeSet.getEncodedListChanges());
        break;
      case SET_TO_LIST_AT_INDEX:
        // No prepared statement for set list element at index
        throw new IllegalStateException("Cannot bind statement to set element at index for list");
      case REMOVE_FROM_LIST_AT_INDEX:
        // No prepared statement for set list element at index
        throw new IllegalStateException(
            "Cannot bind statement to remove element at index for list");
      case ADD_TO_MAP:
        values.add(changeSet.getEncodedMapChanges());
        break;
      case REMOVE_FROM_MAP:
        values.add(changeSet.getEncodedMapChanges().keySet().iterator().next());
        values.add(null);
        break;
    }

    values.addAll(
        fetchPrimaryKeyValues(
            entityMeta, entity, changeSet.getPropertyMeta().structure().isStaticColumn()));
    values.addAll(fetchCASConditionsValues(context, entityMeta));
    BoundStatement bs = ps.bind(values.toArray());

    return new BoundStatementWrapper(
        context.getEntityClass(),
        bs,
        values.toArray(),
        getCQLLevel(consistencyLevel),
        context.getCASResultListener(),
        context.getSerialConsistencyLevel());
  }