Repository: GoogleCloudPlatform/cloud-bigtable-client
Pull request #2082 (2019-02-07 14:06:20)

Removing BigtableDataClient comment from BulkRead
Also, using a different method to construct `Query`


Patch:
diff --git a/bigtable-client-core-parent/bigtable-client-core/src/main/java/com/google/cloud/bigtable/data/v2/internal/RegexUtil.java b/bigtable-client-core-parent/bigtable-client-core/src/main/java/com/google/cloud/bigtable/data/v2/internal/RegexUtil.java
deleted file mode 100644
index 715e69d3e..000000000
--- a/bigtable-client-core-parent/bigtable-client-core/src/main/java/com/google/cloud/bigtable/data/v2/internal/RegexUtil.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright 2018 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.google.cloud.bigtable.data.v2.internal;
-
-import com.google.api.core.InternalApi;
-import com.google.protobuf.ByteString;
-import com.google.protobuf.ByteString.ByteIterator;
-import com.google.protobuf.ByteString.Output;
-import java.io.IOException;
-import java.io.OutputStream;
-
-@Deprecated @InternalApi
-public final class RegexUtil {
-  private static final byte[] NULL_BYTES = "\\x00".getBytes();
-
-  private RegexUtil() {}
-
-  public static String literalRegex(final String value) {
-    return literalRegex(ByteString.copyFromUtf8(value)).toStringUtf8();
-  }
-  /** Converts the value to a quoted regular expression. */
-  public static ByteString literalRegex(ByteString value) {
-    Output output = ByteString.newOutput(value.size() * 2);
-
-    ByteIterator it = value.iterator();
-    try {
-      writeLiteralRegex(it, output);
-    } catch (IOException e) {
-      throw new RuntimeException("Unexpected io error converting regex", e);
-    }
-
-    return output.toByteString();
-  }
-
-  // Extracted from: re2 QuoteMeta:
-  // https://github.com/google/re2/blob/70f66454c255080a54a8da806c52d1f618707f8a/re2/re2.cc#L456
-  private static void writeLiteralRegex(ByteIterator input, OutputStream output)
-      throws IOException {
-    while (input.hasNext()) {
-      byte unquoted = input.nextByte();
-
-      if ((unquoted < 'a' || unquoted > 'z')
-          && (unquoted < 'A' || unquoted > 'Z')
-          && (unquoted < '0' || unquoted > '9')
-          && unquoted != '_'
-          &&
-          // If this is the part of a UTF8 or Latin1 character, we need
-          // to copy this byte without escaping.  Experimentally this is
-          // what works correctly with the regexp library.
-          (unquoted & 128) == 0) {
-
-        if (unquoted == '\0') { // Special handling for null chars.
-          // Note that this special handling is not strictly required for RE2,
-          // but this quoting is required for other regexp libraries such as
-          // PCRE.
-          // Can't use "\\0" since the next character might be a digit.
-          output.write(NULL_BYTES, 0, NULL_BYTES.length);
-          continue;
-        }
-
-        output.write('\\');
-      }
-      output.write(unquoted);
-    }
-  }
-}
diff --git a/bigtable-client-core-parent/bigtable-client-core/src/main/java/com/google/cloud/bigtable/data/v2/wrappers/Filters.java b/bigtable-client-core-parent/bigtable-client-core/src/main/java/com/google/cloud/bigtable/data/v2/wrappers/Filters.java
deleted file mode 100644
index 7765dccc2..000000000
--- a/bigtable-client-core-parent/bigtable-client-core/src/main/java/com/google/cloud/bigtable/data/v2/wrappers/Filters.java
+++ /dev/null
@@ -1,703 +0,0 @@
-/*
- * Copyright 2018 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.google.cloud.bigtable.data.v2.wrappers;
-
-import com.google.api.core.InternalApi;
-import com.google.api.core.InternalExtensionOnly;
-import com.google.bigtable.v2.ColumnRange;
-import com.google.bigtable.v2.RowFilter;
-import com.google.bigtable.v2.ValueRange;
-import com.google.cloud.bigtable.data.v2.internal.RegexUtil;
-import com.google.cloud.bigtable.data.v2.wrappers.Range.AbstractByteStringRange;
-import com.google.cloud.bigtable.data.v2.wrappers.Range.AbstractTimestampRange;
-import com.google.common.base.Preconditions;
-import com.google.protobuf.ByteString;
-import javax.annotation.Nonnull;
-
-/**
- * A Fluent DSL to create a hierarchy of filters for the CheckAndMutateRow RPCs and ReadRows Query.
- *
- * <p>Intended usage is to statically import, or in case of conflict, assign the static variable
- * FILTERS and use its fluent API to build filters.
- *
- * <p>Sample code:
- *
- * <pre>{@code
- * import static com.google.cloud.bigtable.data.v2.wrappers.Filters.FILTERS;
- *
- * void main() {
- *   // Build the filter expression
- *   RowFilter filter = FILTERS.chain()
- *     .filter(FILTERS.qualifier().regex("prefix.*"))
- *     .filter(FILTERS.limit().cellsPerRow(10));
- * }
- *
- * }</pre>
- *
- * @deprecated Please use {@link com.google.cloud.bigtable.data.v2.models.Filters} instead.
- */
-@Deprecated @InternalExtensionOnly
-public final class Filters {
-  /** Entry point into the DSL. */
-  public static final Filters FILTERS = new Filters();
-
-  private static final SimpleFilter PASS =
-      new SimpleFilter(RowFilter.newBuilder().setPassAllFilter(true).build());
-  private static final SimpleFilter BLOCK =
-      new SimpleFilter(RowFilter.newBuilder().setBlockAllFilter(true).build());
-  private static final SimpleFilter SINK =
-      new SimpleFilter(RowFilter.newBuilder().setSink(true).build());
-  private static final SimpleFilter STRIP_VALUE =
-      new SimpleFilter(RowFilter.newBuilder().setStripValueTransformer(true).build());
-
-  private Filters() {}
-
-  /**
-   * Creates an empty chain filter list. Filters can be added to the chain by invoking {@link
-   * ChainFilter#filter(Filters.Filter)}.
-   *
-   * <p>The elements of "filters" are chained together to process the input row:
-   *
-   * <pre>{@code in row -> filter0 -> intermediate row -> filter1 -> ... -> filterN -> out row}
-   * </pre>
-   *
-   * The full chain is executed atomically.
-   */
-  public ChainFilter chain() {
-    return new ChainFilter();
-  }
-
-  /**
-   * Creates an empty interleave filter list. Filters can be added to the interleave by invoking
-   * {@link InterleaveFilter#filter(Filters.Filter)}.
-   *
-   * <p>The elements of "filters" all process a copy of the input row, and the results are pooled,
-   * sorted, and combined into a single output row. If multiple cells are produced with the same
-   * column and timestamp, they will all appear in the output row in an unspecified mutual order.
-   * The full chain is executed atomically.
-   */
-  public InterleaveFilter interleave() {
-    return new InterleaveFilter();
-  }
-
-  /**
-   * Creates an empty condition filter. The filter results of the predicate can be configured by
-   * invoking {@link ConditionFilter#then(Filters.Filter)} and {@link
-   * ConditionFilter#otherwise(Filters.Filter)}.
-   *
-   * <p>A RowFilter which evaluates one of two possible RowFilters, depending on whether or not a
-   * predicate RowFilter outputs any cells from the input row.
-   *
-   * <p>IMPORTANT NOTE: The predicate filter does not execute atomically with the {@link
-   * ConditionFilter#then(Filters.Filter)} and {@link ConditionFilter#otherwise(Filters.Filter)}
-   * (Filter)} filters, which may lead to inconsistent or unexpected results. Additionally, {@link
-   * ConditionFilter} may have poor performance, especially when filters are set for the {@link
-   * ConditionFilter#otherwise(Filters.Filter)}.
-   */
-  public ConditionFilter condition(@Nonnull Filter predicate) {
-    Preconditions.checkNotNull(predicate);
-    return new ConditionFilter(predicate);
-  }
-
-  /** Returns the builder for row key related filters. */
-  public KeyFilter key() {
-    return new KeyFilter();
-  }
-
-  /** Returns the builder for column family related filters. */
-  public FamilyFilter family() {
-    return new FamilyFilter();
-  }
-
-  /** Returns the builder for column qualifier related filters. */
-  public QualifierFilter qualifier() {
-    return new QualifierFilter();
-  }
-
-  /** Returns the builder for timestamp related filters. */
-  public TimestampFilter timestamp() {
-    return new TimestampFilter();
-  }
-
-  /** Returns the builder for value related filters. */
-  public ValueFilter value() {
-    return new ValueFilter();
-  }
-
-  /** Returns the builder for offset related filters. */
-  public OffsetFilter offset() {
-    return new OffsetFilter();
-  }
-
-  /** Returns the builder for limit related filters. */
-  public LimitFilter limit() {
-    return new LimitFilter();
-  }
-
-  // Miscellaneous filters without a clear target.
-  /**
-   * Wraps protobuf representation of a filter.
-   * <p>For advanced use only.
-   */
-  public Filter fromProto(RowFilter rowFilter) {
-    return new SimpleFilter(rowFilter);
-  }
-
-  /** Matches all cells, regardless of input. Functionally equivalent to having no filter. */
-  public Filter pass() {
-    return PASS;
-  }
-
-  /**
-   * Does not match any cells, regardless of input. Useful for temporarily disabling just part of a
-   * filter.
-   */
-  public Filter block() {
-    return BLOCK;
-  }
-
-  /**
-   * Outputs all cells directly to the output of the read rather than to any parent filter. For
-   * advanced usage, see comments in
-   * https://github.com/googleapis/googleapis/blob/master/google/bigtable/v2/data.proto for more
-   * details.
-   */
-  public Filter sink() {
-    return SINK;
-  }
-
-  /**
-   * Applies the given label to all cells in the output row. This allows the caller to determine
-   * which results were produced from which part of the filter.
-   *
-   * <p>Due to a technical limitation, it is not currently possible to apply multiple labels to a
-   * cell. As a result, a {@link ChainFilter} may have no more than one sub-filter which contains a
-   * label. It is okay for an {@link InterleaveFilter} to contain multiple labels, as they will be
-   * applied to separate copies of the input. This may be relaxed in the future.
-   */
-  public Filter label(@Nonnull String label) {
-    Preconditions.checkNotNull(label);
-    return new SimpleFilter(RowFilter.newBuilder().setApplyLabelTransformer(label).build());
-  }
-
-  // Implementations of target specific filters.
-  /** DSL for adding filters to a chain. */
-  public static final class ChainFilter implements Filter {
-    private RowFilter.Chain.Builder builder;
-
-    private ChainFilter() {
-      this.builder = RowFilter.Chain.newBuilder();
-    }
-
-    /** Add a filter to chain. */
-    public ChainFilter filter(@Nonnull Filter filter) {
-      Preconditions.checkNotNull(filter);
-      builder.addFilters(filter.toProto());
-      return this;
-    }
-
-    @InternalApi
-    @Override
-    public RowFilter toProto() {
-      switch (builder.getFiltersCount()) {
-      case 0:
-        return PASS.toProto();
-      case 1:
-        return builder.getFilters(0);
-      default:
-        return RowFilter.newBuilder().setChain(builder.build()).build();
-      }
-    }
-
-    /** Makes a deep copy of the Chain. */
-    @Override
-    public ChainFilter clone() {
-      try {
-        ChainFilter clone = (ChainFilter) super.clone();
-        clone.builder = builder.clone();
-        return clone;
-      } catch (CloneNotSupportedException | ClassCastException e) {
-        throw new RuntimeException("should never happen");
-      }
-    }
-  }
-
-  /** DSL for adding filters to the interleave list. */
-  public static final class InterleaveFilter implements Filter {
-    private RowFilter.Interleave.Builder builder;
-
-    private InterleaveFilter() {
-      builder = RowFilter.Interleave.newBuilder();
-    }
-
-    /** Adds a {@link Filter} to the interleave list. */
-    public InterleaveFilter filter(@Nonnull Filter filter) {
-      Preconditions.checkNotNull(filter);
-      builder.addFilters(filter.toProto());
-      return this;
-    }
-
-    @InternalApi
-    @Override
-    public RowFilter toProto() {
-      switch (builder.getFiltersCount()) {
-      case 0:
-        return PASS.toProto();
-      case 1:
-        return builder.getFilters(0);
-      default:
-        return RowFilter.newBuilder().setInterleave(builder.build()).build();
-      }
-    }
-
-    @Override
-    public InterleaveFilter clone() {
-      try {
-        InterleaveFilter clone = (InterleaveFilter) super.clone();
-        clone.builder = builder.clone();
-        return clone;
-      } catch (CloneNotSupportedException | ClassCastException e) {
-        throw new RuntimeException("should never happen");
-      }
-    }
-  }
-
-  /** DSL for configuring a conditional filter. */
-  public static final class ConditionFilter implements Filter {
-    private RowFilter.Condition.Builder builder;
-
-    private ConditionFilter(@Nonnull Filter predicate) {
-        Preconditions.checkNotNull(predicate);
-        builder = RowFilter.Condition.newBuilder().setPredicateFilter(predicate.toProto());
-    }
-
-    /** Sets (replaces) the filter to apply when the predicate is true. */
-    public ConditionFilter then(@Nonnull Filter filter) {
-      Preconditions.checkNotNull(filter);
-      builder.setTrueFilter(filter.toProto());
-      return this;
-    }
-
-    /** Sets (replaces) the filter to apply when the predicate is false. */
-    public ConditionFilter otherwise(@Nonnull Filter filter) {
-      Preconditions.checkNotNull(filter);
-      builder.setFalseFilter(filter.toProto());
-      return this;
-    }
-
-    @InternalApi
-    @Override
-    public RowFilter toProto() {
-      Preconditions.checkState(
-          builder.hasTrueFilter() || builder.hasFalseFilter(),
-          "ConditionFilter must have either a then or otherwise filter.");
-      return RowFilter.newBuilder().setCondition(builder.build()).build();
-    }
-
-    @Override
-    public ConditionFilter clone() {
-      try {
-        ConditionFilter clone = (ConditionFilter) super.clone();
-        clone.builder = builder.clone();
-        return clone;
-      } catch (CloneNotSupportedException | ClassCastException e) {
-        throw new RuntimeException("should never happen");
-      }
-    }
-  }
-
-  public static final class KeyFilter {
-    private KeyFilter() {}
-
-    /**
-     * Matches only cells from rows whose keys satisfy the given <a
-     * href="https://github.com/google/re2/wiki/Syntax">RE2 regex</a>. In other words, passes
-     * through the entire row when the key matches, and otherwise produces an empty row. Note that,
-     * since row keys can contain arbitrary bytes, the `\C` escape sequence must be used if a true
-     * wildcard is desired. The `.` character will not match the new line character `\n`, which may
-     * be present in a binary key.
-     */
-    public Filter regex(@Nonnull String regex) {
-      Preconditions.checkNotNull(regex);
-      return regex(ByteString.copyFromUtf8(regex));
-    }
-
-    /**
-     * Matches only cells from rows whose keys satisfy the given <a
-     * href="https://github.com/google/re2/wiki/Syntax">RE2 regex</a>. In other words, passes
-     * through the entire row when the key matches, and otherwise produces an empty row. Note that,
-     * since row keys can contain arbitrary bytes, the `\C` escape sequence must be used if a true
-     * wildcard is desired. The `.` character will not match the new line character `\n`, which may
-     * be present in a binary key.
-     */
-    public Filter regex(@Nonnull ByteString regex) {
-      Preconditions.checkNotNull(regex);
-      return new SimpleFilter(RowFilter.newBuilder().setRowKeyRegexFilter(regex).build());
-    }
-
-    /**
-     * Matches only cells from rows whose keys equal the value. In other words, passes through the
-     * entire row when the key matches, and otherwise produces an empty row.
-     */
-    public Filter exactMatch(@Nonnull ByteString value) {
-      Preconditions.checkNotNull(value);
-
-      return regex(RegexUtil.literalRegex(value));
-    }
-
-    /**
-     * Matches all cells from a row with `probability`, and matches no cells from the row with
-     * probability 1-`probability`.
-     */
-    public Filter sample(double probability) {
-      Preconditions.checkArgument(0 <= probability, "Probability must be positive");
-      Preconditions.checkArgument(probability <= 1.0, "Probability must be less than 1.0");
-
-      return new SimpleFilter(RowFilter.newBuilder().setRowSampleFilter(probability).build());
-    }
-  }
-
-  public static final class FamilyFilter {
-    private FamilyFilter() {}
-
-    /**
-     * Matches only cells from columns whose families satisfy the given <a
-     * href="https://github.com/google/re2/wiki/Syntax">RE2 regex</a>. For technical reasons, the
-     * regex must not contain the `:` character, even if it is not being used as a literal. Note
-     * that, since column families cannot contain the new line character `\n`, it is sufficient to
-     * use `.` as a full wildcard when matching column family names.
-     */
-    public Filter regex(@Nonnull String regex) {
-      Preconditions.checkNotNull(regex);
-      return new SimpleFilter(RowFilter.newBuilder().setFamilyNameRegexFilter(regex).build());
-    }
-
-    /** Matches only cells from columns whose families match the value. */
-    public Filter exactMatch(@Nonnull String value) {
-      Preconditions.checkNotNull(value);
-      return regex(RegexUtil.literalRegex(value));
-    }
-  }
-
-  public static final class QualifierFilter {
-    private QualifierFilter() {}
-
-    /**
-     * Matches only cells from columns whose qualifiers satisfy the given <a
-     * href="https://github.com/google/re2/wiki/Syntax">RE2 regex</a>. Note that, since column
-     * qualifiers can contain arbitrary bytes, the `\C` escape sequence must be used if a true
-     * wildcard is desired. The `.` character will not match the new line character `\n`, which may
-     * be present in a binary qualifier.
-     */
-    public Filter regex(@Nonnull String regex) {
-      Preconditions.checkNotNull(regex);
-      return regex(ByteString.copyFromUtf8(regex));
-    }
-
-    /**
-     * Matches only cells from columns whose qualifiers satisfy the given <a
-     * href="https://github.com/google/re2/wiki/Syntax">RE2 regex</a>. Note that, since column
-     * qualifiers can contain arbitrary bytes, the `\C` escape sequence must be used if a true
-     * wildcard is desired. The `.` character will not match the new line character `\n`, which may
-     * be present in a binary qualifier.
-     */
-    public Filter regex(@Nonnull ByteString regex) {
-      Preconditions.checkNotNull(regex);
-
-      return new SimpleFilter(RowFilter.newBuilder().setColumnQualifierRegexFilter(regex).build());
-    }
-
-    /** Matches only cells from columns whose qualifiers equal the value. */
-    public Filter exactMatch(@Nonnull ByteString value) {
-      Preconditions.checkNotNull(value);
-      return regex(RegexUtil.literalRegex(value));
-    }
-
-    /**
-     * Construct a {@link QualifierRangeFilter} that can create a {@link ColumnRange} oriented
-     * {@link Filter}.
-     *
-     * @return a new {@link QualifierRangeFilter}
-     */
-    public QualifierRangeFilter rangeWithinFamily(@Nonnull String family) {
-      Preconditions.checkNotNull(family);
-      return new QualifierRangeFilter(family);
-    }
-  }
-
-  /** Matches only cells from columns within the given range. */
-  public static final class QualifierRangeFilter
-      extends AbstractByteStringRange<QualifierRangeFilter> implements Filter {
-    private final String family;
-
-    private QualifierRangeFilter(String family) {
-      this.family = family;
-    }
-
-    @InternalApi
-    @Override
-    public RowFilter toProto() {
-      ColumnRange.Builder builder = ColumnRange.newBuilder().setFamilyName(family);
-
-      switch (getStartBound()) {
-        case CLOSED:
-          builder.setStartQualifierClosed(getStart());
-          break;
-        case OPEN:
-          builder.setStartQualifierOpen(getStart());
-          break;
-        case UNBOUNDED:
-          break;
-        default:
-          throw new IllegalStateException("Unknown start bound: " + getStartBound());
-      }
-      switch (getEndBound()) {
-        case CLOSED:
-          builder.setEndQualifierClosed(getEnd());
-          break;
-        case OPEN:
-          builder.setEndQualifierOpen(getEnd());
-          break;
-        case UNBOUNDED:
-          break;
-        default:
-          throw new IllegalStateException("Unknown end bound: " + getEndBound());
-      }
-
-      return RowFilter.newBuilder().setColumnRangeFilter(builder.build()).build();
-    }
-
-    @Override
-    public QualifierRangeFilter clone() {
-      return super.clone();
-    }
-  }
-
-  public static final class TimestampFilter {
-    private TimestampFilter() {}
-
-    /**
-     * Matches only cells with timestamps within the given range.
-     *
-     * @return a {@link TimestampRangeFilter} on which start / end timestamps can be specified.
-     */
-    public TimestampRangeFilter range() {
-      return new TimestampRangeFilter();
-    }
-  }
-
-  /**
-   * Matches only cells with microsecond timestamps within the given range.
-   */
-  public static final class TimestampRangeFilter
-      extends AbstractTimestampRange<TimestampRangeFilter> implements Filter {
-    private TimestampRangeFilter() {}
-
-    @InternalApi
-    @Override
-    public RowFilter toProto() {
-      com.google.bigtable.v2.TimestampRange.Builder builder =
-          com.google.bigtable.v2.TimestampRange.newBuilder();
-
-      switch (getStartBound()) {
-        case CLOSED:
-          builder.setStartTimestampMicros(getStart());
-          break;
-        case OPEN:
-          builder.setStartTimestampMicros(getStart() + 1);
-          break;
-        case UNBOUNDED:
-          break;
-        default:
-          throw new IllegalStateException("Unknown start bound: " + getStartBound());
-      }
-      switch (getEndBound()) {
-        case CLOSED:
-          builder.setEndTimestampMicros(getEnd() + 1);
-          break;
-        case OPEN:
-          builder.setEndTimestampMicros(getEnd());
-          break;
-        case UNBOUNDED:
-          break;
-        default:
-          throw new IllegalStateException("Unknown end bound: " + getEndBound());
-      }
-      return RowFilter.newBuilder().setTimestampRangeFilter(builder.build()).build();
-    }
-
-    @Override
-    public TimestampRangeFilter clone() {
-      return super.clone();
-    }
-  }
-
-  public static final class ValueFilter {
-    private ValueFilter() {}
-
-    /**
-     * Matches only cells with values that satisfy the given <a
-     * href="https://github.com/google/re2/wiki/Syntax">RE2 regex</a>. Note that, since cell values
-     * can contain arbitrary bytes, the `\C` escape sequence must be used if a true wildcard is
-     * desired. The `.` character will not match the new line character `\n`, which may be present
-     * in a binary value.
-     */
-    public Filter regex(@Nonnull String regex) {
-      Preconditions.checkNotNull(regex);
-      return regex(ByteString.copyFromUtf8(regex));
-    }
-
-    /** Matches only cells with values that match the given value. */
-    public Filter exactMatch(@Nonnull ByteString value) {
-      Preconditions.checkNotNull(value);
-      return regex(RegexUtil.literalRegex(value));
-    }
-
-    /**
-     * Matches only cells with values that satisfy the given <a
-     * href="https://github.com/google/re2/wiki/Syntax">RE2 regex</a>. Note that, since cell values
-     * can contain arbitrary bytes, the `\C` escape sequence must be used if a true wildcard is
-     * desired. The `.` character will not match the new line character `\n`, which may be present
-     * in a binary value.
-     */
-    public Filter regex(@Nonnull ByteString regex) {
-      Preconditions.checkNotNull(regex);
-      return new SimpleFilter(RowFilter.newBuilder().setValueRegexFilter(regex).build());
-    }
-
-    /**
-     * Construct a {@link ValueRangeFilter} that can create a {@link ValueRange} oriented {@link
-     * Filter}.
-     *
-     * @return a new {@link ValueRangeFilter}
-     */
-    public ValueRangeFilter range() {
-      return new ValueRangeFilter();
-    }
-
-    /** Replaces each cell's value with the empty string. */
-    public Filter strip() {
-      return STRIP_VALUE;
-    }
-  }
-
-  /** Matches only cells with values that fall within the given value range. */
-  public static final class ValueRangeFilter extends AbstractByteStringRange<ValueRangeFilter>
-      implements Filter {
-    private ValueRangeFilter() {}
-
-    @InternalApi
-    @Override
-    public RowFilter toProto() {
-      ValueRange.Builder builder = ValueRange.newBuilder();
-      switch (getStartBound()) {
-        case CLOSED:
-          builder.setStartValueClosed(getStart());
-          break;
-        case OPEN:
-          builder.setStartValueOpen(getStart());
-          break;
-        case UNBOUNDED:
-          break;
-        default:
-          throw new IllegalStateException("Unknown start bound: " + getStartBound());
-      }
-      switch (getEndBound()) {
-        case CLOSED:
-          builder.setEndValueClosed(getEnd());
-          break;
-        case OPEN:
-          builder.setEndValueOpen(getEnd());
-          break;
-        case UNBOUNDED:
-          break;
-        default:
-          throw new IllegalStateException("Unknown end bound: " + getEndBound());
-      }
-      return RowFilter.newBuilder().setValueRangeFilter(builder.build()).build();
-    }
-
-    @Override
-    public ValueRangeFilter clone() {
-      return super.clone();
-    }
-  }
-
-  public static final class OffsetFilter {
-    private OffsetFilter() {}
-
-    /**
-     * Skips the first N cells of each row, matching all subsequent cells. If duplicate cells are
-     * present, as is possible when using an {@link InterleaveFilter}, each copy of the cell is
-     * counted separately.
-     */
-    public Filter cellsPerRow(int count) {
-      return new SimpleFilter(RowFilter.newBuilder().setCellsPerRowOffsetFilter(count).build());
-    }
-  }
-
-  public static final class LimitFilter {
-    private LimitFilter() {}
-
-    /**
-     * Matches only the first N cells of each row. If duplicate cells are present, as is possible
-     * when using an Interleave, each copy of the cell is counted separately.
-     */
-    public Filter cellsPerRow(int count) {
-      return new SimpleFilter(RowFilter.newBuilder().setCellsPerRowLimitFilter(count).build());
-    }
-
-    /**
-     * Matches only the most recent `count` cells within each column. For example, if count=2, this
-     * filter would match column `foo:bar` at timestamps 10 and 9 skip all earlier cells in
-     * `foo:bar`, and then begin matching again in column `foo:bar2`. If duplicate cells are
-     * present, as is possible when using an {@link InterleaveFilter}, each copy of the cell is
-     * counted separately.
-     */
-    public Filter cellsPerColumn(int count) {
-      return new SimpleFilter(RowFilter.newBuilder().setCellsPerColumnLimitFilter(count).build());
-    }
-  }
-
-  private static final class SimpleFilter implements Filter {
-    private final RowFilter proto;
-
-    private SimpleFilter(@Nonnull RowFilter proto) {
-      Preconditions.checkNotNull(proto);
-      this.proto = proto;
-    }
-
-    @InternalApi
-    @Override
-    public RowFilter toProto() {
-      return proto;
-    }
-
-    @Override
-    public SimpleFilter clone() {
-      try {
-        return (SimpleFilter) super.clone();
-      } catch (CloneNotSupportedException e) {
-        throw new RuntimeException("should never happen", e);
-      }
-    }
-  }
-
-  public interface Filter extends Cloneable {
-    @InternalApi
-    RowFilter toProto();
-  }
-}
diff --git a/bigtable-client-core-parent/bigtable-client-core/src/main/java/com/google/cloud/bigtable/data/v2/wrappers/Range.java b/bigtable-client-core-parent/bigtable-client-core/src/main/java/com/google/cloud/bigtable/data/v2/wrappers/Range.java
deleted file mode 100644
index 3f95cc488..000000000
--- a/bigtable-client-core-parent/bigtable-client-core/src/main/java/com/google/cloud/bigtable/data/v2/wrappers/Range.java
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * Copyright 2018 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.google.cloud.bigtable.data.v2.wrappers;
-
-import com.google.common.base.Preconditions;
-import com.google.protobuf.ByteString;
-import javax.annotation.Nonnull;
-
-/**
- * Range API.
- *
- * <p>This base class represents the API for all ranges in the Cloud Bigtable client. Please note
- * this mutable type. It's intended to support fluent DSLs.For example:
- *
- * <pre>{@code
- * // A Range that encloses all strings
- * ByteStringRange.unbounded();
- *
- * // Range that includes all strings including "begin" up until "end"
- * ByteStringRange.unbounded().of("start", "end");
- *
- * // Create a Bytestring range with an unbounded start and the inclusive end "end"
- * ByteStringRange.unbounded().endClosed("end");
- *
- * // Ranges are mutable, so take care to clone them to get a new instance
- * ByteStringRange r1 = ByteStringRange.of("a", "z");
- * ByteStringRange r2 = r1.clone().endUnbounded();
- * }</pre>
- */
-@Deprecated
-abstract class Range<T, R extends Range<T, R>> {
-  public enum BoundType {
-    OPEN,
-    CLOSED,
-    UNBOUNDED
-  }
-
-  private BoundType startBound;
-  private T start;
-  private BoundType endBound;
-  private T end;
-
-  Range() {
-    this(BoundType.UNBOUNDED, null, BoundType.UNBOUNDED, null);
-  }
-
-  Range(BoundType startBound, T start, BoundType endBound, T end) {
-    this.startBound = startBound;
-    this.start = start;
-    this.endBound = endBound;
-    this.end = end;
-  }
-
-  /**
-   * Creates a new {@link Range} with the specified inclusive start and the specified exclusive end.
-   */
-  public R of(@Nonnull T startClosed, @Nonnull T endOpen) {
-    return startClosed(startClosed).endOpen(endOpen);
-  }
-
-  /** Creates a new {@link Range} with an unbounded start and the current end. */
-  public R startUnbounded() {
-    this.start = null;
-    this.startBound = BoundType.UNBOUNDED;
-    return thisT();
-  }
-
-  /** Creates a new {@link Range} with the specified exclusive start and the current end. */
-  public R startOpen(@Nonnull T start) {
-    this.start = Preconditions.checkNotNull(start, "Start can't be null");
-    this.startBound = BoundType.OPEN;
-    return thisT();
-  }
-
-  /** Creates a new {@link Range} with the specified inclusive start and the current end. */
-  public R startClosed(@Nonnull T start) {
-    this.start = Preconditions.checkNotNull(start, "Start can't be null");
-    this.startBound = BoundType.CLOSED;
-    return thisT();
-  }
-
-  /** Creates a new {@link Range} with the current start and an unbounded end. */
-  public R endUnbounded() {
-    this.end = null;
-    this.endBound = BoundType.UNBOUNDED;
-    return thisT();
-  }
-
-  /** Creates a new {@link Range} with the specified exclusive end and the current start. */
-  public R endOpen(@Nonnull T end) {
-    this.end = Preconditions.checkNotNull(end, "End can't be null");
-    this.endBound = BoundType.OPEN;
-    return thisT();
-  }
-
-  /** Creates a new {@link Range} with the specified inclusive end and the current start. */
-  public R endClosed(@Nonnull T end) {
-    this.end = Preconditions.checkNotNull(end, "End can't be null");
-    this.endBound = BoundType.CLOSED;
-    return thisT();
-  }
-
-  /** Gets the current start {@link BoundType}. */
-  public BoundType getStartBound() {
-    return startBound;
-  }
-
-  /**
-   * Gets the current start value.
-   *
-   * @throws IllegalStateException If the current {@link #getStartBound()} is {@link
-   *     BoundType#UNBOUNDED}.
-   */
-  public T getStart() {
-    Preconditions.checkState(startBound != BoundType.UNBOUNDED, "Start is unbounded");
-    return start;
-  }
-
-  /** Gets the current end {@link BoundType}. */
-  public BoundType getEndBound() {
-    return endBound;
-  }
-
-  /**
-   * Gets the current end value.
-   *
-   * @throws IllegalStateException If the current {@link #getEndBound()} is {@link
-   *     BoundType#UNBOUNDED}.
-   */
-  public T getEnd() {
-    Preconditions.checkState(endBound != BoundType.UNBOUNDED, "End is unbounded");
-    return end;
-  }
-
-  @SuppressWarnings("unchecked")
-  private R thisT() {
-    return (R) this;
-  }
-
-  /** Abstract specialization of a {@link Range} for timestamps. */
-  @Deprecated
-  abstract static class AbstractTimestampRange<R extends AbstractTimestampRange<R>>
-      extends Range<Long, R> implements Cloneable {
-    AbstractTimestampRange() {
-      super();
-    }
-
-    AbstractTimestampRange(BoundType startBound, Long start, BoundType endBound, Long end) {
-      super(startBound, start, endBound, end);
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    protected R clone() {
-      try {
-        return (R) super.clone();
-      } catch (CloneNotSupportedException e) {
-        throw new RuntimeException("should never happen", e);
-      }
-    }
-  }
-
-  /**
-   * Abstract specialization of a {@link Range} for {@link ByteString}s. Allows for easy interop
-   * with simple Strings.
-   */
-  @Deprecated
-  abstract static class AbstractByteStringRange<R extends AbstractByteStringRange<R>>
-      extends Range<ByteString, R> implements Cloneable {
-    AbstractByteStringRange() {
-      this(BoundType.UNBOUNDED, null, BoundType.UNBOUNDED, null);
-    }
-
-    AbstractByteStringRange(
-        BoundType startBound, ByteString start, BoundType endBound, ByteString end) {
-      super(startBound, start, endBound, end);
-    }
-
-    /**
-     * Creates a new {@link Range} with the specified inclusive start and the specified exclusive
-     * end.
-     */
-    public R of(String startClosed, String endOpen) {
-      return of(wrap(startClosed), wrap(endOpen));
-    }
-
-    /** Creates a new {@link Range} with the specified exclusive start and the current end. */
-    public R startOpen(String start) {
-      return startOpen(wrap(start));
-    }
-
-    /** Creates a new {@link Range} with the specified inclusive start and the current end. */
-    public R startClosed(String start) {
-      return startClosed(wrap(start));
-    }
-
-    /** Creates a new {@link Range} with the specified exclusive end and the current start. */
-    public R endOpen(String end) {
-      return endOpen(wrap(end));
-    }
-
-    /** Creates a new {@link Range} with the specified inclusive end and the current start. */
-    public R endClosed(String end) {
-      return endClosed(wrap(end));
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    protected R clone() {
-      try {
-        return (R) super.clone();
-      } catch (CloneNotSupportedException e) {
-        throw new RuntimeException("should never happen", e);
-      }
-    }
-
-    static ByteString wrap(String str) {
-      return ByteString.copyFromUtf8(str);
-    }
-  }
-
-  /** Concrete Range for timestamps */
-  @Deprecated
-  public static final class TimestampRange extends AbstractTimestampRange<TimestampRange> {
-    public static TimestampRange unbounded() {
-      return new TimestampRange(BoundType.UNBOUNDED, null, BoundType.UNBOUNDED, null);
-    }
-
-    public static TimestampRange create(long closedStart, long openEnd) {
-      return new TimestampRange(BoundType.CLOSED, closedStart, BoundType.OPEN, openEnd);
-    }
-
-    private TimestampRange(BoundType startBound, Long start, BoundType endBound, Long end) {
-      super(startBound, start, endBound, end);
-    }
-  }
-
-  /** Concrete Range for ByteStrings */
-  @Deprecated
-  public static final class ByteStringRange extends AbstractByteStringRange<ByteStringRange> {
-    public static ByteStringRange unbounded() {
-      return new ByteStringRange(BoundType.UNBOUNDED, null, BoundType.UNBOUNDED, null);
-    }
-
-    public static ByteStringRange create(ByteString closedStart, ByteString openEnd) {
-      return new ByteStringRange(BoundType.CLOSED, closedStart, BoundType.OPEN, openEnd);
-    }
-
-    public static ByteStringRange create(String closedStart, String openEnd) {
-      return new ByteStringRange(
-          BoundType.CLOSED, wrap(closedStart), BoundType.OPEN, wrap(openEnd));
-    }
-
-    private ByteStringRange(
-        BoundType startBound, ByteString start, BoundType endBound, ByteString end) {
-      super(startBound, start, endBound, end);
-    }
-  }
-}
diff --git a/bigtable-client-core-parent/bigtable-client-core/src/main/java/com/google/cloud/bigtable/grpc/BigtableSession.java b/bigtable-client-core-parent/bigtable-client-core/src/main/java/com/google/cloud/bigtable/grpc/BigtableSession.java
index 90c94151e..8d396f2a4 100644
--- a/bigtable-client-core-parent/bigtable-client-core/src/main/java/com/google/cloud/bigtable/grpc/BigtableSession.java
+++ b/bigtable-client-core-parent/bigtable-client-core/src/main/java/com/google/cloud/bigtable/grpc/BigtableSession.java
@@ -29,7 +29,6 @@ import com.google.cloud.bigtable.config.RetryOptions;
 import com.google.cloud.bigtable.core.IBigtableDataClient;
 import com.google.cloud.bigtable.core.IBigtableTableAdminClient;
 import com.google.cloud.bigtable.data.v2.internal.RequestContext;
-import com.google.cloud.bigtable.grpc.async.AsyncExecutor;
 import com.google.cloud.bigtable.grpc.async.BulkMutation;
 import com.google.cloud.bigtable.grpc.async.BulkRead;
 import com.google.cloud.bigtable.grpc.async.ResourceLimiter;
@@ -327,28 +326,6 @@ public class BigtableSession implements Closeable {
     return clientWrapper;
   }
 
-  /**
-   * <p>createAsyncExecutor.</p>
-   *
-   * @return a {@link com.google.cloud.bigtable.grpc.async.AsyncExecutor} object.
-   */
-  public AsyncExecutor createAsyncExecutor() {
-    return new AsyncExecutor(throttlingDataClient);
-  }
-
-  /**
-   * <p>createBulkMutation.</p>
-   *
-   * @param tableName a {@link com.google.cloud.bigtable.grpc.BigtableTableName} object.
-   * @param asyncExecutor a {@link com.google.cloud.bigtable.grpc.async.AsyncExecutor} object.
-   * @return a {@link com.google.cloud.bigtable.grpc.async.BulkMutation} object.
-   * @deprecated use {@link #createBulkMutation(BigtableTableName)} instead.
-   */
-  @Deprecated
-  public BulkMutation createBulkMutation(BigtableTableName tableName, AsyncExecutor asyncExecutor) {
-    return createBulkMutation(tableName);
-  }
-
   /**
    * <p>createBulkMutation.</p>
    *
diff --git a/bigtable-client-core-parent/bigtable-client-core/src/main/java/com/google/cloud/bigtable/grpc/async/AsyncExecutor.java b/bigtable-client-core-parent/bigtable-client-core/src/main/java/com/google/cloud/bigtable/grpc/async/AsyncExecutor.java
deleted file mode 100644
index 9908d51f2..000000000
--- a/bigtable-client-core-parent/bigtable-client-core/src/main/java/com/google/cloud/bigtable/grpc/async/AsyncExecutor.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright 2015 Google Inc. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.google.cloud.bigtable.grpc.async;
-
-import java.io.IOException;
-
-import com.google.bigtable.v2.ReadModifyWriteRowRequest;
-import com.google.bigtable.v2.ReadModifyWriteRowResponse;
-import com.google.cloud.bigtable.config.Logger;
-import com.google.cloud.bigtable.grpc.BigtableDataClient;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-
-/**
- * This class provides management of asynchronous Bigtable RPCs. It ensures that there aren't too
- * many concurrent, in flight asynchronous RPCs and also makes sure that the memory used by the
- * requests doesn't exceed a threshold.
- *
- * @author sduskis
- * @version $Id: $Id
- */
-public class AsyncExecutor {
-
-  /** Constant <code>LOG</code> */
-  protected static final Logger LOG = new Logger(AsyncExecutor.class);
-
-  private final BigtableDataClient client;
-  private final OperationAccountant operationsAccountant;
-
-  /**
-   * <p>
-   * Constructor for AsyncExecutor.
-   * </p>
-   * @param client a {@link com.google.cloud.bigtable.grpc.BigtableDataClient} object for executing
-   *          RPCs.
-   */
-  public AsyncExecutor(BigtableDataClient client) {
-    this(client, new OperationAccountant());
-  }
-
-  /**
-   * <p>
-   * Constructor for AsyncExecutor.
-   * </p>
-   * @param client a {@link com.google.cloud.bigtable.grpc.BigtableDataClient} object for executing
-   *          RPCs.
-   * @param operationAccountant a {@link com.google.cloud.bigtable.grpc.async.OperationAccountant}
-   *          object for tracking the RPCs initiated by this instance.
-   */
-  @VisibleForTesting
-  AsyncExecutor(BigtableDataClient client, OperationAccountant operationAccountant) {
-    this.client = client;
-    this.operationsAccountant = operationAccountant;
-  }
-
-  /**
-   * Performs a {@link com.google.cloud.bigtable.grpc.BigtableDataClient#readModifyWriteRow(ReadModifyWriteRowRequest)} on the
-   * {@link com.google.bigtable.v2.ReadModifyWriteRowRequest}. This method may block if
-   * {@link OperationAccountant#registerOperation(ListenableFuture)} blocks.
-   *
-   * @param request The {@link com.google.bigtable.v2.ReadModifyWriteRowRequest} to send.
-   * @return a {@link com.google.common.util.concurrent.ListenableFuture} which can be listened to for completion events.
-   */
-  public ListenableFuture<ReadModifyWriteRowResponse>
-      readModifyWriteRowAsync(ReadModifyWriteRowRequest request) {
-    // Wait until both the memory and rpc count maximum requirements are achieved before getting a
-    // unique id used to track this request.
-    ListenableFuture<ReadModifyWriteRowResponse> future;
-    try {
-      future = client.readModifyWriteRowAsync(request);
-    } catch (Throwable e) {
-      future = Futures.immediateFailedFuture(e);
-    }
-    operationsAccountant.registerOperation(future);
-    return future;
-  }
-
-  /**
-   * Waits until all operations managed by the
-   * {@link com.google.cloud.bigtable.grpc.async.OperationAccountant} complete. See
-   * {@link com.google.cloud.bigtable.grpc.async.OperationAccountant#awaitCompletion()} for more
-   * information.
-   * @throws java.io.IOException if something goes wrong.
-   */
-  public void flush() throws IOException {
-    LOG.trace("Flushing");
-    try {
-      operationsAccountant.awaitCompletion();
-    } catch (InterruptedException e) {
-      Thread.currentThread().interrupt();
-      throw new IOException("Batch operations were interrupted.");
-    }
-    LOG.trace("Done flushing");
-  }
-
-  /**
-   * <p>
-   * hasInflightRequests.
-   * </p>
-   * @return a boolean.
-   */
-  public boolean hasInflightRequests() {
-    return operationsAccountant.hasInflightOperations();
-  }
-
-}
diff --git a/bigtable-client-core-parent/bigtable-client-core/src/main/java/com/google/cloud/bigtable/grpc/async/BulkMutation.java b/bigtable-client-core-parent/bigtable-client-core/src/main/java/com/google/cloud/bigtable/grpc/async/BulkMutation.java
index 404c49e5e..8c0c8def2 100644
--- a/bigtable-client-core-parent/bigtable-client-core/src/main/java/com/google/cloud/bigtable/grpc/async/BulkMutation.java
+++ b/bigtable-client-core-parent/bigtable-client-core/src/main/java/com/google/cloud/bigtable/grpc/async/BulkMutation.java
@@ -16,6 +16,8 @@
  */
 package com.google.cloud.bigtable.grpc.async;
 
+import com.google.bigtable.v2.ReadModifyWriteRowRequest;
+import com.google.bigtable.v2.ReadModifyWriteRowResponse;
 import com.google.cloud.bigtable.metrics.BigtableClientMetrics.MetricLevel;
 import com.google.api.client.util.NanoClock;
 import com.google.bigtable.v2.MutateRowRequest;
@@ -446,6 +448,29 @@ public class BulkMutation {
     return future;
   }
 
+
+  /**
+   * Performs a {@link com.google.cloud.bigtable.grpc.BigtableDataClient#readModifyWriteRow(ReadModifyWriteRowRequest)} on the
+   * {@link com.google.bigtable.v2.ReadModifyWriteRowRequest}. This method may block if
+   * {@link OperationAccountant#registerOperation(ListenableFuture)} blocks.
+   *
+   * @param request The {@link com.google.bigtable.v2.ReadModifyWriteRowRequest} to send.
+   * @return a {@link com.google.common.util.concurrent.ListenableFuture} which can be listened to for completion events.
+   */
+  public ListenableFuture<ReadModifyWriteRowResponse> readModifyWrite(
+      ReadModifyWriteRowRequest request) {
+    // Wait until both the memory and rpc count maximum requirements are achieved before getting a
+    // unique id used to track this request.
+    ListenableFuture<ReadModifyWriteRowResponse> future;
+    try {
+      future = client.readModifyWriteRowAsync(request);
+    } catch (Throwable e) {
+      future = Futures.immediateFailedFuture(e);
+    }
+    operationAccountant.registerOperation(future);
+    return future;
+  }
+
   /**
    * Send any outstanding {@link MutateRowRequest}s and wait until all requests are complete.
    */
diff --git a/bigtable-client-core-parent/bigtable-client-core/src/main/java/com/google/cloud/bigtable/grpc/async/BulkRead.java b/bigtable-client-core-parent/bigtable-client-core/src/main/java/com/google/cloud/bigtable/grpc/async/BulkRead.java
index 43055aff7..9fd81f19b 100644
--- a/bigtable-client-core-parent/bigtable-client-core/src/main/java/com/google/cloud/bigtable/grpc/async/BulkRead.java
+++ b/bigtable-client-core-parent/bigtable-client-core/src/main/java/com/google/cloud/bigtable/grpc/async/BulkRead.java
@@ -25,11 +25,11 @@ import java.util.Map;
 import java.util.Map.Entry;
 
 import com.google.cloud.bigtable.core.IBigtableDataClient;
+import com.google.cloud.bigtable.data.v2.models.Filters;
 import com.google.cloud.bigtable.data.v2.models.Query;
 import com.google.common.base.Preconditions;
 import com.google.bigtable.v2.ReadRowsRequest;
 import com.google.bigtable.v2.RowFilter;
-import com.google.bigtable.v2.RowSet;
 import com.google.cloud.bigtable.config.Logger;
 import com.google.cloud.bigtable.grpc.BigtableTableName;
 import com.google.cloud.bigtable.grpc.scanner.FlatRow;
@@ -69,7 +69,7 @@ public class BulkRead {
   private final IBigtableDataClient client;
   private final int batchSizes;
   private final ExecutorService threadPool;
-  private final String tableName;
+  private final String tableId;
 
   private final Map<RowFilter, Batch> batches;
 
@@ -83,7 +83,7 @@ public class BulkRead {
   public BulkRead(IBigtableDataClient client, BigtableTableName tableName, int batchSizes,
       ExecutorService threadPool) {
     this.client = client;
-    this.tableName = tableName.toString();
+    this.tableId = tableName.getTableId();
     this.batchSizes = batchSizes;
     this.threadPool = threadPool;
     this.batches = new HashMap<>();
@@ -137,7 +137,7 @@ public class BulkRead {
      * operation is complete. The value of the {@link Multimap} is a {@link SettableFuture} of
      * a {@link List} of {@link FlatRow}s.  The {@link Multimap} is used because a user could request
      * the same key multiple times in the same batch. The {@link List} of {@link FlatRow}s mimics the
-     * interface of {@link BigtableDataClient#readRowsAsync(ReadRowsRequest)}.
+     * interface of {@link IBigtableDataClient#readRowsAsync(Query)}.
      */
     private final Multimap<ByteString, SettableFuture<FlatRow>> futures;
 
@@ -177,14 +177,13 @@ public class BulkRead {
     @Override
     public void run() {
       try {
-        Query query = Query.fromProto(ReadRowsRequest.newBuilder()
-            .setTableName(tableName)
-            .setFilter(filter)
-
-            // TODO: Query.addRowKeys(List<ByteString>) would be super helpful, and allow
-            // this class to construct a Query without passing in a proto
-            .setRows(RowSet.newBuilder().addAllRowKeys(futures.keys()).build())
-            .build());
+        Query query = Query.create(tableId)
+            .filter(Filters.FILTERS.fromProto(filter));
+
+        for(ByteString key : futures.keys()) {
+          query.rowKey(key);
+        }
+
         ResultScanner<FlatRow> scanner = client.readFlatRows(query);
         while (true) {
           FlatRow row = scanner.next();
diff --git a/bigtable-client-core-parent/bigtable-hbase/src/main/java/com/google/cloud/bigtable/hbase/BigtableBufferedMutatorHelper.java b/bigtable-client-core-parent/bigtable-hbase/src/main/java/com/google/cloud/bigtable/hbase/BigtableBufferedMutatorHelper.java
index b773c509a..a9c8ee5ad 100644
--- a/bigtable-client-core-parent/bigtable-hbase/src/main/java/com/google/cloud/bigtable/hbase/BigtableBufferedMutatorHelper.java
+++ b/bigtable-client-core-parent/bigtable-hbase/src/main/java/com/google/cloud/bigtable/hbase/BigtableBufferedMutatorHelper.java
@@ -15,7 +15,9 @@
  */
 package com.google.cloud.bigtable.hbase;
 
+import com.google.bigtable.v2.MutateRowsRequest;
 import com.google.cloud.bigtable.data.v2.internal.RequestContext;
+import com.google.cloud.bigtable.data.v2.models.RowMutation;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
@@ -35,7 +37,6 @@ import com.google.cloud.bigtable.config.BigtableOptions;
 import com.google.cloud.bigtable.config.Logger;
 import com.google.cloud.bigtable.grpc.BigtableSession;
 import com.google.cloud.bigtable.grpc.BigtableTableName;
-import com.google.cloud.bigtable.grpc.async.AsyncExecutor;
 import com.google.cloud.bigtable.grpc.async.BulkMutation;
 import com.google.cloud.bigtable.hbase.adapters.HBaseRequestAdapter;
 import com.google.common.util.concurrent.Futures;
@@ -65,7 +66,6 @@ public class BigtableBufferedMutatorHelper {
   private boolean closed = false;
 
   private final HBaseRequestAdapter adapter;
-  private final AsyncExecutor asyncExecutor;
 
   private final BulkMutation bulkMutation;
 
@@ -92,7 +92,6 @@ public class BigtableBufferedMutatorHelper {
     this.adapter = adapter;
     this.configuration = configuration;
     this.options = session.getOptions();
-    this.asyncExecutor = session.createAsyncExecutor();
     BigtableTableName tableName = this.adapter.getBigtableTableName();
     this.bulkMutation = session.createBulkMutation(tableName);
     this.requestContext = session.getDataRequestContext();
@@ -102,7 +101,6 @@ public class BigtableBufferedMutatorHelper {
     closedWriteLock.lock();
     try {
       flush();
-      asyncExecutor.flush();
       closed = true;
     } finally {
       closedWriteLock.unlock();
@@ -119,7 +117,6 @@ public class BigtableBufferedMutatorHelper {
         throw new IOException("flush() was interrupted", e);
       }
     }
-    asyncExecutor.flush();
   }
 
   public void sendUnsent() {
@@ -189,7 +186,7 @@ public class BigtableBufferedMutatorHelper {
         return Futures.immediateFailedFuture(
             new IllegalArgumentException("Cannot perform a mutation on a null object."));
       } else {
-        return bulkMutation.add(adapter.adaptEntry(mutation));
+        return bulkMutation.add(toEntry(adapter.adaptEntry(mutation)));
       }
     } finally {
       closedReadLock.unlock();
@@ -208,15 +205,14 @@ public class BigtableBufferedMutatorHelper {
         future = Futures.immediateFailedFuture(
           new IllegalArgumentException("Cannot perform a mutation on a null object."));
       } else if (mutation instanceof Put) {
-        future = bulkMutation.add(adapter.adaptEntry((Put) mutation));
+        future = bulkMutation.add(toEntry(adapter.adaptEntry((Put) mutation)));
       } else if (mutation instanceof Delete) {
-        future = bulkMutation.add(adapter.adaptEntry((Delete) mutation));
+        future = bulkMutation.add(toEntry(adapter.adaptEntry((Delete) mutation)));
       } else if (mutation instanceof Increment) {
-        future =
-            asyncExecutor.readModifyWriteRowAsync(
-                adapter.adapt((Increment) mutation).toProto(requestContext));
+        future = bulkMutation.readModifyWrite(
+            adapter.adapt((Increment) mutation).toProto(requestContext));
       } else if (mutation instanceof Append) {
-        future = asyncExecutor.readModifyWriteRowAsync(
+        future = bulkMutation.readModifyWrite(
             adapter.adapt((Append) mutation).toProto(requestContext));
       } else {
         future = Futures.immediateFailedFuture(new IllegalArgumentException(
@@ -230,6 +226,9 @@ public class BigtableBufferedMutatorHelper {
     return future;
   }
 
+  private MutateRowsRequest.Entry toEntry(RowMutation rowMutation) {
+    return rowMutation.toBulkProto(requestContext).getEntries(0);
+  }
 
   /**
    * <p>hasInflightRequests.</p>
@@ -237,7 +236,6 @@ public class BigtableBufferedMutatorHelper {
    * @return a boolean.
    */
   public boolean hasInflightRequests() {
-    return this.asyncExecutor.hasInflightRequests()
-        || (bulkMutation != null && !bulkMutation.isFlushed());
+    return bulkMutation != null && !bulkMutation.isFlushed();
   }
 }
diff --git a/bigtable-client-core-parent/bigtable-hbase/src/main/java/com/google/cloud/bigtable/hbase/adapters/HBaseRequestAdapter.java b/bigtable-client-core-parent/bigtable-hbase/src/main/java/com/google/cloud/bigtable/hbase/adapters/HBaseRequestAdapter.java
index 549c54441..9e83ab314 100644
--- a/bigtable-client-core-parent/bigtable-hbase/src/main/java/com/google/cloud/bigtable/hbase/adapters/HBaseRequestAdapter.java
+++ b/bigtable-client-core-parent/bigtable-hbase/src/main/java/com/google/cloud/bigtable/hbase/adapters/HBaseRequestAdapter.java
@@ -16,7 +16,6 @@
 package com.google.cloud.bigtable.hbase.adapters;
 
 import com.google.api.core.InternalApi;
-import com.google.cloud.bigtable.data.v2.internal.RequestContext;
 import com.google.cloud.bigtable.data.v2.models.Mutation;
 import com.google.cloud.bigtable.data.v2.models.MutationApi;
 import com.google.cloud.bigtable.data.v2.models.Query;
@@ -34,8 +33,6 @@ import org.apache.hadoop.hbase.client.Put;
 import org.apache.hadoop.hbase.client.RowMutations;
 import org.apache.hadoop.hbase.client.Scan;
 
-import com.google.bigtable.v2.MutateRowRequest;
-import com.google.bigtable.v2.MutateRowsRequest;
 import com.google.cloud.bigtable.config.BigtableOptions;
 import com.google.cloud.bigtable.grpc.BigtableTableName;
 import com.google.cloud.bigtable.hbase.adapters.read.DefaultReadHooks;
@@ -74,7 +71,6 @@ public class HBaseRequestAdapter {
   protected final MutationAdapters mutationAdapters;
   protected final TableName tableName;
   protected final BigtableTableName bigtableTableName;
-  protected final RequestContext requestContext;
 
   /**
    * <p>Constructor for HBaseRequestAdapter.</p>
@@ -99,9 +95,7 @@ public class HBaseRequestAdapter {
                              MutationAdapters mutationAdapters) {
     this(tableName,
         options.getInstanceName().toTableName(tableName.getQualifierAsString()),
-        mutationAdapters,
-        RequestContext
-            .create(options.getProjectId(), options.getInstanceId(), options.getAppProfileId()));
+        mutationAdapters);
   }
 
   /**
@@ -114,16 +108,14 @@ public class HBaseRequestAdapter {
   @VisibleForTesting
   HBaseRequestAdapter(TableName tableName,
                               BigtableTableName bigtableTableName,
-                              MutationAdapters mutationAdapters,
-                              RequestContext requestContext) {
+                              MutationAdapters mutationAdapters) {
     this.tableName = tableName;
     this.bigtableTableName = bigtableTableName;
     this.mutationAdapters = mutationAdapters;
-    this.requestContext = requestContext;
   }
 
   public HBaseRequestAdapter withServerSideTimestamps(){
-    return new HBaseRequestAdapter(tableName, bigtableTableName, mutationAdapters.withServerSideTimestamps(), requestContext);
+    return new HBaseRequestAdapter(tableName, bigtableTableName, mutationAdapters.withServerSideTimestamps());
   }
 
   /**
@@ -155,10 +147,10 @@ public class HBaseRequestAdapter {
    * @param delete a {@link org.apache.hadoop.hbase.client.Delete} object.
    * @return a {@link com.google.bigtable.v2.MutateRowsRequest.Entry} object.
    */
-  public MutateRowsRequest.Entry adaptEntry(Delete delete) {
+  public RowMutation adaptEntry(Delete delete) {
     RowMutation rowMutation = newRowMutationModel(delete.getRow());
     adapt(delete, rowMutation);
-    return toEntry(rowMutation);
+    return rowMutation;
   }
 
   /**
@@ -243,10 +235,10 @@ public class HBaseRequestAdapter {
    * @param put a {@link org.apache.hadoop.hbase.client.Put} object.
    * @return a {@link com.google.bigtable.v2.MutateRowsRequest.Entry} object.
    */
-  public MutateRowsRequest.Entry adaptEntry(Put put) {
+  public RowMutation adaptEntry(Put put) {
     RowMutation rowMutation = newRowMutationModel(put.getRow());
     adapt(put, rowMutation);
-    return toEntry(rowMutation);
+    return rowMutation;
   }
 
   /**
@@ -278,10 +270,10 @@ public class HBaseRequestAdapter {
    * @param mutations a {@link org.apache.hadoop.hbase.client.RowMutations} object.
    * @return a {@link com.google.bigtable.v2.MutateRowsRequest.Entry} object.
    */
-  public MutateRowsRequest.Entry adaptEntry(RowMutations mutations) {
+  public RowMutation adaptEntry(RowMutations mutations) {
     RowMutation rowMutation = newRowMutationModel(mutations.getRow());
     adapt(mutations, rowMutation);
-    return toEntry(rowMutation);
+    return rowMutation;
   }
 
   /**
@@ -290,10 +282,10 @@ public class HBaseRequestAdapter {
    * @param mutation a {@link org.apache.hadoop.hbase.client.Mutation} object.
    * @return a {@link com.google.bigtable.v2.MutateRowRequest} object.
    */
-  public MutateRowRequest adapt(org.apache.hadoop.hbase.client.Mutation mutation) {
+  public RowMutation adapt(org.apache.hadoop.hbase.client.Mutation mutation) {
     RowMutation rowMutation = newRowMutationModel(mutation.getRow());
     adapt(mutation, rowMutation);
-    return rowMutation.toProto(requestContext);
+    return rowMutation;
   }
 
   /**
@@ -334,10 +326,6 @@ public class HBaseRequestAdapter {
     return getBigtableTableName().toString();
   }
 
-  private MutateRowsRequest.Entry toEntry(RowMutation rowMutation) {
-    return rowMutation.toBulkProto(requestContext).getEntries(0);
-  }
-
   private RowMutation newRowMutationModel(byte [] rowKey) {
     if (!mutationAdapters.putAdapter.isSetClientTimestamp()) {
       return RowMutation.create(
diff --git a/bigtable-client-core-parent/bigtable-hbase/src/main/java/com/google/cloud/bigtable/hbase/filter/BigtableFilter.java b/bigtable-client-core-parent/bigtable-hbase/src/main/java/com/google/cloud/bigtable/hbase/filter/BigtableFilter.java
index 8a6dc81ff..ade019749 100644
--- a/bigtable-client-core-parent/bigtable-hbase/src/main/java/com/google/cloud/bigtable/hbase/filter/BigtableFilter.java
+++ b/bigtable-client-core-parent/bigtable-hbase/src/main/java/com/google/cloud/bigtable/hbase/filter/BigtableFilter.java
@@ -17,9 +17,9 @@ package com.google.cloud.bigtable.hbase.filter;
 
 import static com.google.cloud.bigtable.data.v2.models.Filters.FILTERS;
 
-import java.io.IOException;
 import java.io.Serializable;
 
+import com.google.cloud.bigtable.data.v2.models.Filters;
 import org.apache.hadoop.hbase.Cell;
 import org.apache.hadoop.hbase.exceptions.DeserializationException;
 import org.apache.hadoop.hbase.filter.Filter;
@@ -27,7 +27,6 @@ import org.apache.hadoop.hbase.filter.FilterBase;
 import org.apache.hadoop.hbase.filter.FilterList;
 
 import com.google.bigtable.v2.RowFilter;
-import com.google.cloud.bigtable.data.v2.models.Filters;
 import com.google.protobuf.InvalidProtocolBufferException;
 
 /**
@@ -47,13 +46,8 @@ public class BigtableFilter extends FilterBase implements Serializable {
     this.filter = filter;
   }
 
-  @Deprecated
-  public BigtableFilter(com.google.cloud.bigtable.data.v2.wrappers.Filters.Filter filter) {
-    this(FILTERS.fromProto(filter.toProto()));
-  }
-
   @Override
-  public ReturnCode filterKeyValue(Cell cell) throws IOException {
+  public ReturnCode filterKeyValue(Cell cell) {
     return ReturnCode.SKIP;
   }
 
@@ -71,7 +65,7 @@ public class BigtableFilter extends FilterBase implements Serializable {
   }
 
   @Override
-  public byte[] toByteArray() throws IOException {
+  public byte[] toByteArray() {
     return filter.toProto().toByteArray();
   }
 


Test patch:
diff --git a/bigtable-client-core-parent/bigtable-client-core/src/test/java/com/google/cloud/bigtable/data/v2/wrappers/FiltersTest.java b/bigtable-client-core-parent/bigtable-client-core/src/test/java/com/google/cloud/bigtable/data/v2/wrappers/FiltersTest.java
deleted file mode 100644
index d4737114c..000000000
--- a/bigtable-client-core-parent/bigtable-client-core/src/test/java/com/google/cloud/bigtable/data/v2/wrappers/FiltersTest.java
+++ /dev/null
@@ -1,436 +0,0 @@
-/*
- * Copyright 2018 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.google.cloud.bigtable.data.v2.wrappers;
-
-import static com.google.cloud.bigtable.data.v2.wrappers.Filters.FILTERS;
-
-import com.google.bigtable.v2.ColumnRange;
-import com.google.bigtable.v2.RowFilter;
-import com.google.bigtable.v2.RowFilter.Chain;
-import com.google.bigtable.v2.RowFilter.Condition;
-import com.google.bigtable.v2.RowFilter.Interleave;
-import com.google.bigtable.v2.TimestampRange;
-import com.google.bigtable.v2.ValueRange;
-import com.google.protobuf.ByteString;
-import org.junit.Assert;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class FiltersTest {
-  @Test
-  public void chainTest() {
-    RowFilter actualProto =
-        FILTERS
-            .chain()
-            .filter(FILTERS.key().regex(".*"))
-            .filter(FILTERS.key().sample(0.5))
-            .filter(FILTERS.chain().filter(FILTERS.family().regex("hi$")).filter(FILTERS.pass()))
-            .toProto();
-
-    RowFilter expectedFilter =
-        RowFilter.newBuilder()
-            .setChain(
-                Chain.newBuilder()
-                    .addFilters(
-                        RowFilter.newBuilder().setRowKeyRegexFilter(ByteString.copyFromUtf8(".*")))
-                    .addFilters(RowFilter.newBuilder().setRowSampleFilter(0.5))
-                    .addFilters(
-                        RowFilter.newBuilder()
-                            .setChain(
-                                Chain.newBuilder()
-                                    .addFilters(
-                                        RowFilter.newBuilder().setFamilyNameRegexFilter("hi$"))
-                                    .addFilters(RowFilter.newBuilder().setPassAllFilter(true)))))
-            .build();
-
-    Assert.assertEquals(expectedFilter, actualProto);
-  }
-
-  @Test
-  public void interleaveTest() {
-    RowFilter actualProto =
-        FILTERS
-            .interleave()
-            .filter(FILTERS.key().regex(".*"))
-            .filter(FILTERS.key().sample(0.5))
-            .filter(
-                FILTERS.interleave().filter(FILTERS.family().regex("hi$")).filter(FILTERS.pass()))
-            .toProto();
-
-    RowFilter expectedFilter =
-        RowFilter.newBuilder()
-            .setInterleave(
-                Interleave.newBuilder()
-                    .addFilters(
-                        RowFilter.newBuilder().setRowKeyRegexFilter(ByteString.copyFromUtf8(".*")))
-                    .addFilters(RowFilter.newBuilder().setRowSampleFilter(0.5))
-                    .addFilters(
-                        RowFilter.newBuilder()
-                            .setInterleave(
-                                Interleave.newBuilder()
-                                    .addFilters(
-                                        RowFilter.newBuilder().setFamilyNameRegexFilter("hi$"))
-                                    .addFilters(
-                                        RowFilter.newBuilder().setPassAllFilter(true).build()))))
-            .build();
-
-    Assert.assertEquals(expectedFilter, actualProto);
-  }
-
-  @Test
-  public void conditionTest() {
-    RowFilter actualFilter =
-        FILTERS
-            .condition(FILTERS.key().regex(".*"))
-            .then(FILTERS.label("true"))
-            .otherwise(FILTERS.label("false"))
-            .toProto();
-
-    RowFilter expectedFilter =
-        RowFilter.newBuilder()
-            .setCondition(
-                Condition.newBuilder()
-                    .setPredicateFilter(
-                        RowFilter.newBuilder().setRowKeyRegexFilter(ByteString.copyFromUtf8(".*")))
-                    .setTrueFilter(RowFilter.newBuilder().setApplyLabelTransformer("true"))
-                    .setFalseFilter(RowFilter.newBuilder().setApplyLabelTransformer("false")))
-            .build();
-
-    Assert.assertEquals(expectedFilter, actualFilter);
-  }
-
-  @Test
-  public void keyRegexTest() {
-    RowFilter actualFilter = FILTERS.key().regex(ByteString.copyFromUtf8(".*")).toProto();
-
-    RowFilter expectedFilter =
-        RowFilter.newBuilder().setRowKeyRegexFilter(ByteString.copyFromUtf8(".*")).build();
-
-    Assert.assertEquals(expectedFilter, actualFilter);
-  }
-
-  @Test
-  public void keyRegexStringTest() {
-    RowFilter actualFilter = FILTERS.key().regex(".*").toProto();
-
-    RowFilter expectedFilter =
-        RowFilter.newBuilder().setRowKeyRegexFilter(ByteString.copyFromUtf8(".*")).build();
-
-    Assert.assertEquals(expectedFilter, actualFilter);
-  }
-
-  @Test
-  public void keyExactMatchTest() {
-    RowFilter actualFilter = FILTERS.key().exactMatch(ByteString.copyFromUtf8(".*")).toProto();
-
-    RowFilter expectedFilter =
-        RowFilter.newBuilder().setRowKeyRegexFilter(ByteString.copyFromUtf8("\\.\\*")).build();
-
-    Assert.assertEquals(expectedFilter, actualFilter);
-  }
-
-  @Test
-  public void keySampleTest() {
-    RowFilter actualFilter = FILTERS.key().sample(0.3).toProto();
-
-    RowFilter expectedFilter = RowFilter.newBuilder().setRowSampleFilter(0.3).build();
-
-    Assert.assertEquals(expectedFilter, actualFilter);
-  }
-
-  @Test
-  public void familyRegexTest() {
-    RowFilter actualFilter = FILTERS.family().regex("^hi").toProto();
-
-    RowFilter expectedFilter = RowFilter.newBuilder().setFamilyNameRegexFilter("^hi").build();
-
-    Assert.assertEquals(expectedFilter, actualFilter);
-  }
-
-  @Test
-  public void familyExactMatchTest() {
-    RowFilter actualFilter = FILTERS.family().exactMatch("^hi").toProto();
-
-    RowFilter expectedFilter = RowFilter.newBuilder().setFamilyNameRegexFilter("\\^hi").build();
-
-    Assert.assertEquals(expectedFilter, actualFilter);
-  }
-
-  @Test
-  public void qualifierRegexTest() {
-    RowFilter actualFilter = FILTERS.qualifier().regex(ByteString.copyFromUtf8("^hi")).toProto();
-
-    RowFilter expectedFilter =
-        RowFilter.newBuilder()
-            .setColumnQualifierRegexFilter(ByteString.copyFromUtf8("^hi"))
-            .build();
-
-    Assert.assertEquals(expectedFilter, actualFilter);
-  }
-
-  @Test
-  public void qualifierRegexStringTest() {
-    RowFilter actualFilter = FILTERS.qualifier().regex("^hi").toProto();
-
-    RowFilter expectedFilter =
-        RowFilter.newBuilder()
-            .setColumnQualifierRegexFilter(ByteString.copyFromUtf8("^hi"))
-            .build();
-
-    Assert.assertEquals(expectedFilter, actualFilter);
-  }
-
-  @Test
-  public void qualifierExactMatchTest() {
-    RowFilter actualFilter =
-        FILTERS.qualifier().exactMatch(ByteString.copyFromUtf8("^hi")).toProto();
-
-    RowFilter expectedFilter =
-        RowFilter.newBuilder()
-            .setColumnQualifierRegexFilter(ByteString.copyFromUtf8("\\^hi"))
-            .build();
-
-    Assert.assertEquals(expectedFilter, actualFilter);
-  }
-
-  @Test
-  public void qualifierRangeInFamilyClosedOpen() {
-    RowFilter actualFilter =
-        FILTERS
-            .qualifier()
-            .rangeWithinFamily("family")
-            .startClosed("begin")
-            .endOpen("end")
-            .toProto();
-
-    RowFilter expectedFilter =
-        RowFilter.newBuilder()
-            .setColumnRangeFilter(
-                ColumnRange.newBuilder()
-                    .setFamilyName("family")
-                    .setStartQualifierClosed(ByteString.copyFromUtf8("begin"))
-                    .setEndQualifierOpen(ByteString.copyFromUtf8("end")))
-            .build();
-
-    Assert.assertEquals(expectedFilter, actualFilter);
-  }
-
-  @Test
-  public void qualifierRangeInFamilyOpenClosed() {
-    RowFilter actualFilter =
-        FILTERS
-            .qualifier()
-            .rangeWithinFamily("family")
-            .startOpen("begin")
-            .endClosed("end")
-            .toProto();
-
-    RowFilter expectedFilter =
-        RowFilter.newBuilder()
-            .setColumnRangeFilter(
-                ColumnRange.newBuilder()
-                    .setFamilyName("family")
-                    .setStartQualifierOpen(ByteString.copyFromUtf8("begin"))
-                    .setEndQualifierClosed(ByteString.copyFromUtf8("end")))
-            .build();
-
-    Assert.assertEquals(expectedFilter, actualFilter);
-  }
-
-  @Test
-  public void qualifierRangeRange() {
-    RowFilter actualFilter =
-        FILTERS
-            .qualifier()
-            .rangeWithinFamily("family")
-            .startClosed("begin")
-            .endOpen("end")
-            .toProto();
-
-    RowFilter expectedFilter =
-        RowFilter.newBuilder()
-            .setColumnRangeFilter(
-                ColumnRange.newBuilder()
-                    .setFamilyName("family")
-                    .setStartQualifierClosed(ByteString.copyFromUtf8("begin"))
-                    .setEndQualifierOpen(ByteString.copyFromUtf8("end")))
-            .build();
-
-    Assert.assertEquals(expectedFilter, actualFilter);
-  }
-
-  @Test
-  public void timestampRange() {
-    RowFilter actualFilter =
-        FILTERS.timestamp().range().startClosed(1_000L).endOpen(30_000L).toProto();
-
-    RowFilter expectedFilter =
-        RowFilter.newBuilder()
-            .setTimestampRangeFilter(
-                TimestampRange.newBuilder()
-                    .setStartTimestampMicros(1_000L)
-                    .setEndTimestampMicros(30_000L))
-            .build();
-
-    Assert.assertEquals(expectedFilter, actualFilter);
-  }
-
-  @Test
-  public void timestampOpenClosedFakeRange() {
-    RowFilter actualFilter =
-        FILTERS.timestamp().range().startOpen(1_000L).endClosed(30_000L).toProto();
-
-    // open start & closed end are faked in the client by incrementing the query
-    RowFilter expectedFilter =
-        RowFilter.newBuilder()
-            .setTimestampRangeFilter(
-                TimestampRange.newBuilder()
-                    .setStartTimestampMicros(1_000L + 1)
-                    .setEndTimestampMicros(30_000L + 1))
-            .build();
-
-    Assert.assertEquals(expectedFilter, actualFilter);
-  }
-
-  @Test
-  public void valueRegex() {
-    RowFilter actualFilter = FILTERS.value().regex("some[0-9]regex").toProto();
-
-    RowFilter expectedFilter =
-        RowFilter.newBuilder()
-            .setValueRegexFilter(ByteString.copyFromUtf8("some[0-9]regex"))
-            .build();
-
-    Assert.assertEquals(expectedFilter, actualFilter);
-  }
-
-  @Test
-  public void valueExactMatch() {
-    RowFilter actualFilter =
-        FILTERS.value().exactMatch(ByteString.copyFromUtf8("some[0-9]regex")).toProto();
-
-    RowFilter expectedFilter =
-        RowFilter.newBuilder()
-            .setValueRegexFilter(ByteString.copyFromUtf8("some\\[0\\-9\\]regex"))
-            .build();
-
-    Assert.assertEquals(expectedFilter, actualFilter);
-  }
-
-  @Test
-  public void valueRangeClosedOpen() {
-    RowFilter actualFilter = FILTERS.value().range().startClosed("begin").endOpen("end").toProto();
-
-    RowFilter expectedFilter =
-        RowFilter.newBuilder()
-            .setValueRangeFilter(
-                ValueRange.newBuilder()
-                    .setStartValueClosed(ByteString.copyFromUtf8("begin"))
-                    .setEndValueOpen(ByteString.copyFromUtf8("end")))
-            .build();
-
-    Assert.assertEquals(expectedFilter, actualFilter);
-  }
-
-  @Test
-  public void valueRangeOpenClosed() {
-    RowFilter actualFilter = FILTERS.value().range().startOpen("begin").endClosed("end").toProto();
-
-    RowFilter expectedFilter =
-        RowFilter.newBuilder()
-            .setValueRangeFilter(
-                ValueRange.newBuilder()
-                    .setStartValueOpen(ByteString.copyFromUtf8("begin"))
-                    .setEndValueClosed(ByteString.copyFromUtf8("end")))
-            .build();
-
-    Assert.assertEquals(expectedFilter, actualFilter);
-  }
-
-  @Test
-  public void valueStripTest() {
-    RowFilter actualFilter = FILTERS.value().strip().toProto();
-
-    RowFilter expectedFilter = RowFilter.newBuilder().setStripValueTransformer(true).build();
-
-    Assert.assertEquals(expectedFilter, actualFilter);
-  }
-
-  @Test
-  public void offsetCellsPerRowTest() {
-    RowFilter actualFilter = FILTERS.offset().cellsPerRow(10).toProto();
-
-    RowFilter expectedFilter = RowFilter.newBuilder().setCellsPerRowOffsetFilter(10).build();
-
-    Assert.assertEquals(expectedFilter, actualFilter);
-  }
-
-  @Test
-  public void limitCellsPerRowTest() {
-    RowFilter actualFilter = FILTERS.limit().cellsPerRow(10).toProto();
-
-    RowFilter expectedFilter = RowFilter.newBuilder().setCellsPerRowLimitFilter(10).build();
-
-    Assert.assertEquals(expectedFilter, actualFilter);
-  }
-
-  @Test
-  public void limitCellsPerColumnTest() {
-    RowFilter actualFilter = FILTERS.limit().cellsPerColumn(10).toProto();
-
-    RowFilter expectedFilter = RowFilter.newBuilder().setCellsPerColumnLimitFilter(10).build();
-
-    Assert.assertEquals(expectedFilter, actualFilter);
-  }
-
-  @Test
-  public void passTest() {
-    RowFilter actualFilter = FILTERS.pass().toProto();
-
-    RowFilter expectedFilter = RowFilter.newBuilder().setPassAllFilter(true).build();
-
-    Assert.assertEquals(expectedFilter, actualFilter);
-  }
-
-  @Test
-  public void blockTest() {
-    RowFilter actualFilter = FILTERS.block().toProto();
-
-    RowFilter expectedFilter = RowFilter.newBuilder().setBlockAllFilter(true).build();
-
-    Assert.assertEquals(expectedFilter, actualFilter);
-  }
-
-  @Test
-  public void sinkTest() {
-    RowFilter actualFilter = FILTERS.sink().toProto();
-
-    RowFilter expectedFilter = RowFilter.newBuilder().setSink(true).build();
-
-    Assert.assertEquals(expectedFilter, actualFilter);
-  }
-
-  @Test
-  public void labelTest() {
-    RowFilter actualFilter = FILTERS.label("my-label").toProto();
-
-    RowFilter expectedFilter = RowFilter.newBuilder().setApplyLabelTransformer("my-label").build();
-
-    Assert.assertEquals(expectedFilter, actualFilter);
-  }
-}
diff --git a/bigtable-client-core-parent/bigtable-client-core/src/test/java/com/google/cloud/bigtable/data/v2/wrappers/RangeTest.java b/bigtable-client-core-parent/bigtable-client-core/src/test/java/com/google/cloud/bigtable/data/v2/wrappers/RangeTest.java
deleted file mode 100644
index 4d400d086..000000000
--- a/bigtable-client-core-parent/bigtable-client-core/src/test/java/com/google/cloud/bigtable/data/v2/wrappers/RangeTest.java
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * Copyright 2018 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.google.cloud.bigtable.data.v2.wrappers;
-
-import com.google.cloud.bigtable.data.v2.wrappers.Range.BoundType;
-import com.google.cloud.bigtable.data.v2.wrappers.Range.ByteStringRange;
-import com.google.cloud.bigtable.data.v2.wrappers.Range.TimestampRange;
-import com.google.protobuf.ByteString;
-import org.junit.Assert;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class RangeTest {
-  @Test
-  public void timestampUnboundedTest() {
-    TimestampRange range = TimestampRange.unbounded();
-    Assert.assertEquals(BoundType.UNBOUNDED, range.getStartBound());
-    Assert.assertEquals(BoundType.UNBOUNDED, range.getEndBound());
-
-    Throwable actualError = null;
-    try {
-      //noinspection ResultOfMethodCallIgnored
-      range.getStart();
-    } catch (Throwable e) {
-      actualError = e;
-    }
-    Assert.assertTrue(actualError instanceof IllegalStateException);
-
-    try {
-      //noinspection ResultOfMethodCallIgnored
-      range.getEnd();
-    } catch (Throwable e) {
-      actualError = e;
-    }
-    Assert.assertTrue(actualError instanceof IllegalStateException);
-  }
-
-  @Test
-  public void timestampOfTest() {
-    TimestampRange range = TimestampRange.create(10, 2_000);
-    Assert.assertEquals(BoundType.CLOSED, range.getStartBound());
-    Assert.assertEquals(10, range.getStart().longValue());
-    Assert.assertEquals(BoundType.OPEN, range.getEndBound());
-    Assert.assertEquals(2_000, range.getEnd().longValue());
-  }
-
-  @Test
-  public void timestampChangeStartTest() {
-    TimestampRange range = TimestampRange.create(10, 2_000).startOpen(20L);
-
-    Assert.assertEquals(BoundType.OPEN, range.getEndBound());
-    Assert.assertEquals(2_000, range.getEnd().longValue());
-
-    Assert.assertEquals(BoundType.OPEN, range.getStartBound());
-    Assert.assertEquals(20, range.getStart().longValue());
-
-    range = range.startClosed(30L);
-    Assert.assertEquals(BoundType.CLOSED, range.getStartBound());
-    Assert.assertEquals(30, range.getStart().longValue());
-  }
-
-  @Test
-  public void timestampChangeEndTest() {
-    TimestampRange range = TimestampRange.create(10, 2_000).endClosed(1_000L);
-
-    Assert.assertEquals(BoundType.CLOSED, range.getStartBound());
-    Assert.assertEquals(10, range.getStart().longValue());
-
-    Assert.assertEquals(BoundType.CLOSED, range.getEndBound());
-    Assert.assertEquals(1_000, range.getEnd().longValue());
-
-    range = range.endOpen(3_000L);
-    Assert.assertEquals(BoundType.OPEN, range.getEndBound());
-    Assert.assertEquals(3_000, range.getEnd().longValue());
-  }
-
-  @Test
-  public void byteStringUnboundedTest() {
-    ByteStringRange range = ByteStringRange.unbounded();
-    Assert.assertEquals(BoundType.UNBOUNDED, range.getStartBound());
-    Assert.assertEquals(BoundType.UNBOUNDED, range.getEndBound());
-
-    Throwable actualError = null;
-    try {
-      range.getStart();
-    } catch (Throwable e) {
-      actualError = e;
-    }
-    Assert.assertTrue(actualError instanceof IllegalStateException);
-
-    try {
-      range.getEnd();
-    } catch (Throwable e) {
-      actualError = e;
-    }
-    Assert.assertTrue(actualError instanceof IllegalStateException);
-  }
-
-  @Test
-  public void byteStringOfTest() {
-    ByteStringRange range =
-        ByteStringRange.create(ByteString.copyFromUtf8("a"), ByteString.copyFromUtf8("b"));
-
-    Assert.assertEquals(BoundType.CLOSED, range.getStartBound());
-    Assert.assertEquals(ByteString.copyFromUtf8("a"), range.getStart());
-    Assert.assertEquals(BoundType.OPEN, range.getEndBound());
-    Assert.assertEquals(ByteString.copyFromUtf8("b"), range.getEnd());
-  }
-
-  @Test
-  public void byteStringOfStringTest() {
-    ByteStringRange range = ByteStringRange.create("a", "b");
-
-    Assert.assertEquals(BoundType.CLOSED, range.getStartBound());
-    Assert.assertEquals(ByteString.copyFromUtf8("a"), range.getStart());
-    Assert.assertEquals(BoundType.OPEN, range.getEndBound());
-    Assert.assertEquals(ByteString.copyFromUtf8("b"), range.getEnd());
-  }
-
-  @Test
-  public void byteStringChangeStartTest() {
-    ByteStringRange range =
-        ByteStringRange.create(ByteString.copyFromUtf8("a"), ByteString.copyFromUtf8("z"))
-            .startOpen(ByteString.copyFromUtf8("b"));
-
-    Assert.assertEquals(BoundType.OPEN, range.getEndBound());
-    Assert.assertEquals(ByteString.copyFromUtf8("z"), range.getEnd());
-
-    Assert.assertEquals(BoundType.OPEN, range.getStartBound());
-    Assert.assertEquals(ByteString.copyFromUtf8("b"), range.getStart());
-
-    range = range.startClosed(ByteString.copyFromUtf8("c"));
-    Assert.assertEquals(BoundType.CLOSED, range.getStartBound());
-    Assert.assertEquals(ByteString.copyFromUtf8("c"), range.getStart());
-  }
-
-  @Test
-  public void byteStringChangeStartStringTest() {
-    ByteStringRange range = ByteStringRange.create("a", "z").startOpen("b");
-
-    Assert.assertEquals(BoundType.OPEN, range.getEndBound());
-    Assert.assertEquals(ByteString.copyFromUtf8("z"), range.getEnd());
-
-    Assert.assertEquals(BoundType.OPEN, range.getStartBound());
-    Assert.assertEquals(ByteString.copyFromUtf8("b"), range.getStart());
-
-    range = range.startClosed("c");
-    Assert.assertEquals(BoundType.CLOSED, range.getStartBound());
-    Assert.assertEquals(ByteString.copyFromUtf8("c"), range.getStart());
-  }
-
-  @Test
-  public void byteStringChangeEndTest() {
-    ByteStringRange range =
-        ByteStringRange.create(ByteString.copyFromUtf8("a"), ByteString.copyFromUtf8("z"))
-            .endClosed(ByteString.copyFromUtf8("y"));
-
-    Assert.assertEquals(BoundType.CLOSED, range.getStartBound());
-    Assert.assertEquals(ByteString.copyFromUtf8("a"), range.getStart());
-
-    Assert.assertEquals(BoundType.CLOSED, range.getEndBound());
-    Assert.assertEquals(ByteString.copyFromUtf8("y"), range.getEnd());
-
-    range = range.endOpen(ByteString.copyFromUtf8("x"));
-    Assert.assertEquals(BoundType.OPEN, range.getEndBound());
-    Assert.assertEquals(ByteString.copyFromUtf8("x"), range.getEnd());
-  }
-
-  @Test
-  public void byteStringChangeEndStringTest() {
-    ByteStringRange range = ByteStringRange.create("a", "z").endClosed("y");
-
-    Assert.assertEquals(BoundType.CLOSED, range.getStartBound());
-    Assert.assertEquals(ByteString.copyFromUtf8("a"), range.getStart());
-
-    Assert.assertEquals(BoundType.CLOSED, range.getEndBound());
-    Assert.assertEquals(ByteString.copyFromUtf8("y"), range.getEnd());
-
-    range = range.endOpen("x");
-    Assert.assertEquals(BoundType.OPEN, range.getEndBound());
-    Assert.assertEquals(ByteString.copyFromUtf8("x"), range.getEnd());
-  }
-}
diff --git a/bigtable-client-core-parent/bigtable-client-core/src/test/java/com/google/cloud/bigtable/grpc/async/TestAsyncExecutor.java b/bigtable-client-core-parent/bigtable-client-core/src/test/java/com/google/cloud/bigtable/grpc/async/TestAsyncExecutor.java
deleted file mode 100644
index 8cec21fde..000000000
--- a/bigtable-client-core-parent/bigtable-client-core/src/test/java/com/google/cloud/bigtable/grpc/async/TestAsyncExecutor.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright 2015 Google Inc. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.google.cloud.bigtable.grpc.async;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.when;
-
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import com.google.bigtable.v2.CheckAndMutateRowRequest;
-import com.google.bigtable.v2.MutateRowRequest;
-import com.google.bigtable.v2.ReadModifyWriteRowRequest;
-import com.google.bigtable.v2.ReadRowsRequest;
-import com.google.bigtable.v2.ReadRowsResponse;
-import com.google.cloud.bigtable.grpc.BigtableDataClient;
-import com.google.common.util.concurrent.SettableFuture;
-
-/**
- * Tests for {@link AsyncExecutor}
- */
-@SuppressWarnings("unchecked")
-@RunWith(JUnit4.class)
-public class TestAsyncExecutor {
-
-  @Mock
-  private BigtableDataClient client;
-
-  @SuppressWarnings("rawtypes")
-  private SettableFuture future;
-
-  private AsyncExecutor underTest;
-
-
-  @Before
-  public void setUp() {
-    MockitoAnnotations.initMocks(this);
-    underTest = new AsyncExecutor(client);
-    future = SettableFuture.create();
-  }
-
-  @Test
-  public void testNoMutation() {
-    Assert.assertFalse(underTest.hasInflightRequests());
-  }
-
-
-  @Test
-  public void testReadWriteModify()  {
-    when(client.readModifyWriteRowAsync(any(ReadModifyWriteRowRequest.class))).thenReturn(future);
-    underTest.readModifyWriteRowAsync(ReadModifyWriteRowRequest.getDefaultInstance());
-    Assert.assertTrue(underTest.hasInflightRequests());
-    future.set("");
-    Assert.assertFalse(underTest.hasInflightRequests());
-  }
-
-  @Test
-  public void testInvalidMutation() {
-    when(client.readModifyWriteRowAsync(any(ReadModifyWriteRowRequest.class))).thenThrow(new RuntimeException());
-    underTest.readModifyWriteRowAsync(ReadModifyWriteRowRequest.getDefaultInstance());
-    future.set(ReadRowsResponse.getDefaultInstance());
-    Assert.assertFalse(underTest.hasInflightRequests());
-  }
-}
diff --git a/bigtable-client-core-parent/bigtable-client-core/src/test/java/com/google/cloud/bigtable/grpc/async/TestBulkMutation.java b/bigtable-client-core-parent/bigtable-client-core/src/test/java/com/google/cloud/bigtable/grpc/async/TestBulkMutation.java
index 4dede139b..16e609bbd 100644
--- a/bigtable-client-core-parent/bigtable-client-core/src/test/java/com/google/cloud/bigtable/grpc/async/TestBulkMutation.java
+++ b/bigtable-client-core-parent/bigtable-client-core/src/test/java/com/google/cloud/bigtable/grpc/async/TestBulkMutation.java
@@ -29,6 +29,9 @@ import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicLong;
 
+import com.google.bigtable.v2.ReadModifyWriteRowRequest;
+import com.google.bigtable.v2.ReadModifyWriteRowResponse;
+import com.google.bigtable.v2.ReadRowsResponse;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
@@ -172,6 +175,7 @@ public class TestBulkMutation {
     }
   }
 
+  @Test
   public void testCallableTooFewStatuses() throws Exception {
     ListenableFuture<MutateRowResponse> rowFuture1 = underTest.add(createRequestEntry());
     ListenableFuture<MutateRowResponse> rowFuture2 = underTest.add(createRequestEntry());
@@ -198,6 +202,7 @@ public class TestBulkMutation {
     }
   }
 
+  @Test
   public void testRunOutOfTime() throws Exception {
     ListenableFuture<MutateRowResponse> rowFuture = underTest.add(createRequestEntry());
     setResponse(Status.DEADLINE_EXCEEDED);
@@ -367,6 +372,23 @@ public class TestBulkMutation {
     underTest.add(bigRequest.build());
   }
 
+  @Test
+  public void testReadWriteModify()  {
+    SettableFuture<ReadModifyWriteRowResponse> future = SettableFuture.create();
+    when(client.readModifyWriteRowAsync(any(ReadModifyWriteRowRequest.class))).thenReturn(future);
+    underTest.readModifyWrite(ReadModifyWriteRowRequest.getDefaultInstance());
+    Assert.assertTrue(operationAccountant.hasInflightOperations());
+    future.set(ReadModifyWriteRowResponse.getDefaultInstance());
+    Assert.assertFalse(operationAccountant.hasInflightOperations());
+  }
+
+  @Test
+  public void testInvalidMutation() {
+    when(client.readModifyWriteRowAsync(any(ReadModifyWriteRowRequest.class))).thenThrow(new RuntimeException());
+    underTest.readModifyWrite(ReadModifyWriteRowRequest.getDefaultInstance());
+    Assert.assertFalse(operationAccountant.hasInflightOperations());
+  }
+
   private BulkMutation createBulkMutation() {
     return new BulkMutation(TABLE_NAME, client, operationAccountant, retryExecutorService,
         BULK_OPTIONS);
diff --git a/bigtable-client-core-parent/bigtable-hbase/src/test/java/com/google/cloud/bigtable/hbase/TestBatchExecutor.java b/bigtable-client-core-parent/bigtable-hbase/src/test/java/com/google/cloud/bigtable/hbase/TestBatchExecutor.java
index ba669109d..ad668059c 100644
--- a/bigtable-client-core-parent/bigtable-hbase/src/test/java/com/google/cloud/bigtable/hbase/TestBatchExecutor.java
+++ b/bigtable-client-core-parent/bigtable-hbase/src/test/java/com/google/cloud/bigtable/hbase/TestBatchExecutor.java
@@ -31,7 +31,6 @@ import com.google.cloud.bigtable.config.BigtableOptions;
 import com.google.cloud.bigtable.data.v2.internal.RequestContext;
 import com.google.cloud.bigtable.grpc.BigtableSession;
 import com.google.cloud.bigtable.grpc.BigtableTableName;
-import com.google.cloud.bigtable.grpc.async.AsyncExecutor;
 import com.google.cloud.bigtable.grpc.async.BulkMutation;
 import com.google.cloud.bigtable.grpc.async.BulkRead;
 import com.google.cloud.bigtable.grpc.scanner.FlatRow;
@@ -118,9 +117,6 @@ public class TestBatchExecutor {
   @Mock
   private BigtableSession mockBigtableSession;
 
-  @Mock
-  private AsyncExecutor mockAsyncExecutor;
-
   @Mock
   private BulkRead mockBulkRead;
 
@@ -147,8 +143,7 @@ public class TestBatchExecutor {
 
     MockitoAnnotations.initMocks(this);
     when(mockBulkMutation.add(any(MutateRowsRequest.Entry.class))).thenReturn(mockFuture);
-    when(mockAsyncExecutor.readModifyWriteRowAsync(any(ReadModifyWriteRowRequest.class))).thenReturn(mockFuture);
-    when(mockBigtableSession.createAsyncExecutor()).thenReturn(mockAsyncExecutor);
+    when(mockBulkMutation.readModifyWrite(any(ReadModifyWriteRowRequest.class))).thenReturn(mockFuture);
     when(mockBigtableSession.getDataRequestContext()).thenReturn(requetsContext);
     when(mockBigtableSession.createBulkMutation(any(BigtableTableName.class))).thenReturn(mockBulkMutation);
     when(mockBigtableSession.createBulkRead(any(BigtableTableName.class))).thenReturn(mockBulkRead);
diff --git a/bigtable-client-core-parent/bigtable-hbase/src/test/java/com/google/cloud/bigtable/hbase/TestBigtableBufferedMutator.java b/bigtable-client-core-parent/bigtable-hbase/src/test/java/com/google/cloud/bigtable/hbase/TestBigtableBufferedMutator.java
index 58ce1ef54..8973f3621 100644
--- a/bigtable-client-core-parent/bigtable-hbase/src/test/java/com/google/cloud/bigtable/hbase/TestBigtableBufferedMutator.java
+++ b/bigtable-client-core-parent/bigtable-hbase/src/test/java/com/google/cloud/bigtable/hbase/TestBigtableBufferedMutator.java
@@ -49,7 +49,6 @@ import com.google.bigtable.v2.ReadModifyWriteRowRequest;
 import com.google.cloud.bigtable.config.BigtableOptions;
 import com.google.cloud.bigtable.grpc.BigtableSession;
 import com.google.cloud.bigtable.grpc.BigtableTableName;
-import com.google.cloud.bigtable.grpc.async.AsyncExecutor;
 import com.google.cloud.bigtable.grpc.async.BulkMutation;
 import com.google.cloud.bigtable.hbase.adapters.HBaseRequestAdapter;
 import com.google.common.util.concurrent.Futures;
@@ -69,9 +68,6 @@ public class TestBigtableBufferedMutator {
   @Mock
   private BigtableSession mockSession;
 
-  @Mock
-  private AsyncExecutor mockAsyncExecutor;
-
   @Mock
   private BulkMutation mockBulkMutation;
 
@@ -86,7 +82,6 @@ public class TestBigtableBufferedMutator {
   @Before
   public void setUp() {
     MockitoAnnotations.initMocks(this);
-    when(mockSession.createAsyncExecutor()).thenReturn(mockAsyncExecutor);
     when(mockSession.createBulkMutation(any(BigtableTableName.class))).thenReturn(mockBulkMutation);
     when(mockSession.getDataRequestContext())
         .thenReturn(RequestContext.create("project", "instance", ""));
@@ -131,22 +126,22 @@ public class TestBigtableBufferedMutator {
 
   @Test
   public void testIncrement() throws IOException {
-    when(mockAsyncExecutor.readModifyWriteRowAsync(any(ReadModifyWriteRowRequest.class)))
+    when(mockBulkMutation.readModifyWrite(any(ReadModifyWriteRowRequest.class)))
         .thenReturn(future);
     BigtableBufferedMutator underTest = createMutator(new Configuration(false));
     underTest.mutate(new Increment(EMPTY_BYTES).addColumn(EMPTY_BYTES, EMPTY_BYTES, 1));
-    verify(mockAsyncExecutor, times(1))
-        .readModifyWriteRowAsync(any(ReadModifyWriteRowRequest.class));
+    verify(mockBulkMutation, times(1))
+        .readModifyWrite(any(ReadModifyWriteRowRequest.class));
   }
 
   @Test
   public void testAppend() throws IOException {
-    when(mockAsyncExecutor.readModifyWriteRowAsync(any(ReadModifyWriteRowRequest.class)))
+    when(mockBulkMutation.readModifyWrite(any(ReadModifyWriteRowRequest.class)))
         .thenReturn(future);
     BigtableBufferedMutator underTest = createMutator(new Configuration(false));
     underTest.mutate(new Append(EMPTY_BYTES).add(EMPTY_BYTES, EMPTY_BYTES, EMPTY_BYTES));
-    verify(mockAsyncExecutor, times(1))
-        .readModifyWriteRowAsync(any(ReadModifyWriteRowRequest.class));
+    verify(mockBulkMutation, times(1))
+        .readModifyWrite(any(ReadModifyWriteRowRequest.class));
   }
 
   @Test
@@ -172,7 +167,6 @@ public class TestBigtableBufferedMutator {
     verify(mockBulkMutation, times(1)).add(any(MutateRowsRequest.Entry.class));
     underTest.flush();
     verify(mockBulkMutation, times(1)).flush();
-    verify(mockAsyncExecutor, times(1)).flush();
   }
 
   @Test
@@ -187,6 +181,5 @@ public class TestBigtableBufferedMutator {
     verify(mockBulkMutation, times(count)).add(any(MutateRowsRequest.Entry.class));
     underTest.flush();
     verify(mockBulkMutation, times(1)).flush();
-    verify(mockAsyncExecutor, times(1)).flush();
   }
 }
diff --git a/bigtable-client-core-parent/bigtable-hbase/src/test/java/com/google/cloud/bigtable/hbase/adapters/TestCheckAndMutateUtil.java b/bigtable-client-core-parent/bigtable-hbase/src/test/java/com/google/cloud/bigtable/hbase/adapters/TestCheckAndMutateUtil.java
index 05cd9323a..7ef0eab3a 100644
--- a/bigtable-client-core-parent/bigtable-hbase/src/test/java/com/google/cloud/bigtable/hbase/adapters/TestCheckAndMutateUtil.java
+++ b/bigtable-client-core-parent/bigtable-hbase/src/test/java/com/google/cloud/bigtable/hbase/adapters/TestCheckAndMutateUtil.java
@@ -75,11 +75,7 @@ public class TestCheckAndMutateUtil {
     requestAdapter = new HBaseRequestAdapter(
         TABLE_NAME,
         BT_TABLE_NAME,
-        mutationAdapters,
-        RequestContext.create(
-            InstanceName.of(BT_TABLE_NAME.getProjectId(), BT_TABLE_NAME.getInstanceId()),
-            "APP_PROFILE_ID"
-        ));
+        mutationAdapters);
   }
 
   private static void checkPredicate(CheckAndMutateRowRequest result) {