You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by ms...@apache.org on 2016/08/16 22:42:43 UTC

[42/50] [abbrv] cassandra git commit: Merge branch cassandra-2.1 into cassandra-2.2

http://git-wip-us.apache.org/repos/asf/cassandra/blob/9583b6b3/test/unit/org/apache/cassandra/cql3/restrictions/PrimaryKeyRestrictionSetTest.java
----------------------------------------------------------------------
diff --cc test/unit/org/apache/cassandra/cql3/restrictions/PrimaryKeyRestrictionSetTest.java
index bf5128f,0000000..bd5395a
mode 100644,000000..100644
--- a/test/unit/org/apache/cassandra/cql3/restrictions/PrimaryKeyRestrictionSetTest.java
+++ b/test/unit/org/apache/cassandra/cql3/restrictions/PrimaryKeyRestrictionSetTest.java
@@@ -1,1957 -1,0 +1,1957 @@@
 +/*
 + * Licensed to the Apache Software Foundation (ASF) under one
 + * or more contributor license agreements.  See the NOTICE file
 + * distributed with this work for additional information
 + * regarding copyright ownership.  The ASF licenses this file
 + * to you 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 org.apache.cassandra.cql3.restrictions;
 +
 +import java.nio.ByteBuffer;
 +import java.util.ArrayList;
 +import java.util.List;
 +
 +import org.junit.Test;
 +
 +import org.apache.cassandra.config.CFMetaData;
 +import org.apache.cassandra.config.ColumnDefinition;
 +import org.apache.cassandra.cql3.*;
 +import org.apache.cassandra.cql3.Term.MultiItemTerminal;
 +import org.apache.cassandra.cql3.statements.Bound;
 +import org.apache.cassandra.db.ColumnFamilyType;
 +import org.apache.cassandra.db.composites.Composite;
 +import org.apache.cassandra.db.composites.Composite.EOC;
 +import org.apache.cassandra.db.composites.Composites;
 +import org.apache.cassandra.db.composites.CompoundSparseCellNameType;
 +import org.apache.cassandra.db.marshal.AbstractType;
 +import org.apache.cassandra.db.marshal.Int32Type;
 +import org.apache.cassandra.db.marshal.ReversedType;
 +import org.apache.cassandra.utils.ByteBufferUtil;
 +
 +import static java.util.Arrays.asList;
 +import static org.junit.Assert.assertEquals;
 +import static org.junit.Assert.assertTrue;
 +
 +public class PrimaryKeyRestrictionSetTest
 +{
 +    @Test
 +    public void testBoundsAsCompositesWithNoRestrictions()
 +    {
 +        CFMetaData cfMetaData = newCFMetaData(Sort.ASC);
 +
 +        PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +
-         List<Composite> bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        List<Composite> bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertEmptyComposite(bounds.get(0));
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertEmptyComposite(bounds.get(0));
 +    }
 +
 +    /**
 +     * Test 'clustering_0 = 1' with only one clustering column
 +     */
 +    @Test
 +    public void testBoundsAsCompositesWithOneEqRestrictionsAndOneClusteringColumn()
 +    {
 +        CFMetaData cfMetaData = newCFMetaData(Sort.ASC);
 +
 +        ByteBuffer clustering_0 = ByteBufferUtil.bytes(1);
 +        Restriction eq = newSingleEq(cfMetaData, 0, clustering_0);
 +
 +        PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(eq);
 +
-         List<Composite> bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        List<Composite> bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), clustering_0, EOC.START);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), clustering_0, EOC.END);
 +    }
 +
 +    /**
 +     * Test 'clustering_1 = 1' with 2 clustering columns
 +     */
 +    @Test
 +    public void testBoundsAsCompositesWithOneEqRestrictionsAndTwoClusteringColumns()
 +    {
 +        CFMetaData cfMetaData = newCFMetaData(Sort.ASC, Sort.ASC);
 +
 +        ByteBuffer clustering_0 = ByteBufferUtil.bytes(1);
 +        Restriction eq = newSingleEq(cfMetaData, 0, clustering_0);
 +
 +        PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(eq);
 +
-         List<Composite> bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        List<Composite> bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), clustering_0, EOC.START);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), clustering_0, EOC.END);
 +    }
 +
 +    /**
 +     * Test 'clustering_0 IN (1, 2, 3)' with only one clustering column
 +     */
 +    @Test
 +    public void testBoundsAsCompositesWithOneInRestrictionsAndOneClusteringColumn()
 +    {
 +        ByteBuffer value1 = ByteBufferUtil.bytes(1);
 +        ByteBuffer value2 = ByteBufferUtil.bytes(2);
 +        ByteBuffer value3 = ByteBufferUtil.bytes(3);
 +
 +        CFMetaData cfMetaData = newCFMetaData(Sort.ASC, Sort.ASC);
 +
 +        Restriction in = newSingleIN(cfMetaData, 0, value1, value2, value3);
 +
 +        PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(in);
 +
-         List<Composite> bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        List<Composite> bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(3, bounds.size());
 +        assertComposite(bounds.get(0), value1, EOC.START);
 +        assertComposite(bounds.get(1), value2, EOC.START);
 +        assertComposite(bounds.get(2), value3, EOC.START);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(3, bounds.size());
 +        assertComposite(bounds.get(0), value1, EOC.END);
 +        assertComposite(bounds.get(1), value2, EOC.END);
 +        assertComposite(bounds.get(2), value3, EOC.END);
 +    }
 +
 +    /**
 +     * Test slice restriction (e.g 'clustering_0 > 1') with only one clustering column
 +     */
 +    @Test
 +    public void testBoundsAsCompositesWithSliceRestrictionsAndOneClusteringColumn()
 +    {
 +        CFMetaData cfMetaData = newCFMetaData(Sort.ASC, Sort.ASC);
 +
 +        ByteBuffer value1 = ByteBufferUtil.bytes(1);
 +        ByteBuffer value2 = ByteBufferUtil.bytes(2);
 +
 +        Restriction slice = newSingleSlice(cfMetaData, 0, Bound.START, false, value1);
 +        PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice);
 +
-         List<Composite> bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        List<Composite> bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value1, EOC.END);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertEmptyComposite(bounds.get(0));
 +
 +        slice = newSingleSlice(cfMetaData, 0, Bound.START, true, value1);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value1, EOC.NONE);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertEmptyComposite(bounds.get(0));
 +
 +        slice = newSingleSlice(cfMetaData, 0, Bound.END, true, value1);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertEmptyComposite(bounds.get(0));
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value1, EOC.END);
 +
 +        slice = newSingleSlice(cfMetaData, 0, Bound.END, false, value1);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertEmptyComposite(bounds.get(0));
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value1, EOC.START);
 +
 +        slice = newSingleSlice(cfMetaData, 0, Bound.START, false, value1);
 +        Restriction slice2 = newSingleSlice(cfMetaData, 0, Bound.END, false, value2);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value1, EOC.END);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value2, EOC.START);
 +
 +        slice = newSingleSlice(cfMetaData, 0, Bound.START, true, value1);
 +        slice2 = newSingleSlice(cfMetaData, 0, Bound.END, true, value2);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value1, EOC.NONE);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value2, EOC.END);
 +    }
 +
 +    /**
 +     * Test slice restriction (e.g 'clustering_0 > 1') with only one descending clustering column
 +     */
 +    @Test
 +    public void testBoundsAsCompositesWithSliceRestrictionsAndOneDescendingClusteringColumn()
 +    {
 +        CFMetaData cfMetaData = newCFMetaData(Sort.DESC, Sort.DESC);
 +
 +        ByteBuffer value1 = ByteBufferUtil.bytes(1);
 +        ByteBuffer value2 = ByteBufferUtil.bytes(2);
 +
 +        Restriction slice = newSingleSlice(cfMetaData, 0, Bound.START, false, value1);
 +        PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice);
 +
-         List<Composite> bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        List<Composite> bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertEmptyComposite(bounds.get(0));
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value1, EOC.START);
 +
 +        slice = newSingleSlice(cfMetaData, 0, Bound.START, true, value1);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertEmptyComposite(bounds.get(0));
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value1, EOC.END);
 +
 +        slice = newSingleSlice(cfMetaData, 0, Bound.END, true, value1);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value1, EOC.NONE);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertEmptyComposite(bounds.get(0));
 +
 +        slice = newSingleSlice(cfMetaData, 0, Bound.END, false, value1);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value1, EOC.END);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertEmptyComposite(bounds.get(0));
 +
 +        slice = newSingleSlice(cfMetaData, 0, Bound.START, false, value1);
 +        Restriction slice2 = newSingleSlice(cfMetaData, 0, Bound.END, false, value2);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value2, EOC.END);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value1, EOC.START);
 +
 +        slice = newSingleSlice(cfMetaData, 0, Bound.START, true, value1);
 +        slice2 = newSingleSlice(cfMetaData, 0, Bound.END, true, value2);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value2, EOC.NONE);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value1, EOC.END);
 +    }
 +
 +    /**
 +     * Test 'clustering_0 = 1 AND clustering_1 IN (1, 2, 3)'
 +     */
 +    @Test
 +    public void testBoundsAsCompositesWithEqAndInRestrictions()
 +    {
 +        CFMetaData cfMetaData = newCFMetaData(Sort.ASC, Sort.ASC);
 +
 +        ByteBuffer value1 = ByteBufferUtil.bytes(1);
 +        ByteBuffer value2 = ByteBufferUtil.bytes(2);
 +        ByteBuffer value3 = ByteBufferUtil.bytes(3);
 +        Restriction eq = newSingleEq(cfMetaData, 0, value1);
 +        Restriction in = newSingleIN(cfMetaData, 1, value1, value2, value3);
 +        PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(eq).mergeWith(in);
 +
-         List<Composite> bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        List<Composite> bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(3, bounds.size());
 +        assertComposite(bounds.get(0), value1, value1, EOC.START);
 +        assertComposite(bounds.get(1), value1, value2, EOC.START);
 +        assertComposite(bounds.get(2), value1, value3, EOC.START);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(3, bounds.size());
 +        assertComposite(bounds.get(0), value1, value1, EOC.END);
 +        assertComposite(bounds.get(1), value1, value2, EOC.END);
 +        assertComposite(bounds.get(2), value1, value3, EOC.END);
 +    }
 +
 +    /**
 +     * Test equal and slice restrictions (e.g 'clustering_0 = 0 clustering_1 > 1')
 +     */
 +    @Test
 +    public void testBoundsAsCompositesWithEqAndSliceRestrictions()
 +    {
 +        CFMetaData cfMetaData = newCFMetaData(Sort.ASC, Sort.ASC);
 +
 +        ByteBuffer value1 = ByteBufferUtil.bytes(1);
 +        ByteBuffer value2 = ByteBufferUtil.bytes(2);
 +        ByteBuffer value3 = ByteBufferUtil.bytes(3);
 +
 +        Restriction eq = newSingleEq(cfMetaData, 0, value3);
 +
 +        Restriction slice = newSingleSlice(cfMetaData, 1, Bound.START, false, value1);
 +        PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(eq).mergeWith(slice);
 +
-         List<Composite> bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        List<Composite> bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value3, value1, EOC.END);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value3, EOC.END);
 +
 +        slice = newSingleSlice(cfMetaData, 1, Bound.START, true, value1);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(eq).mergeWith(slice);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value3, value1, EOC.NONE);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value3, EOC.END);
 +
 +        slice = newSingleSlice(cfMetaData, 1, Bound.END, true, value1);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(eq).mergeWith(slice);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value3, EOC.START);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value3, value1, EOC.END);
 +
 +        slice = newSingleSlice(cfMetaData, 1, Bound.END, false, value1);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(eq).mergeWith(slice);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value3, EOC.START);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value3, value1, EOC.START);
 +
 +        slice = newSingleSlice(cfMetaData, 1, Bound.START, false, value1);
 +        Restriction slice2 = newSingleSlice(cfMetaData, 1, Bound.END, false, value2);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(eq).mergeWith(slice).mergeWith(slice2);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value3, value1, EOC.END);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value3, value2, EOC.START);
 +
 +        slice = newSingleSlice(cfMetaData, 1, Bound.START, true, value1);
 +        slice2 = newSingleSlice(cfMetaData, 1, Bound.END, true, value2);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(eq).mergeWith(slice).mergeWith(slice2);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value3, value1, EOC.NONE);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value3, value2, EOC.END);
 +    }
 +
 +    /**
 +     * Test '(clustering_0, clustering_1) = (1, 2)' with two clustering column
 +     */
 +    @Test
 +    public void testBoundsAsCompositesWithMultiEqRestrictions()
 +    {
 +        CFMetaData cfMetaData = newCFMetaData(Sort.ASC, Sort.ASC);
 +
 +        ByteBuffer value1 = ByteBufferUtil.bytes(1);
 +        ByteBuffer value2 = ByteBufferUtil.bytes(2);
 +        Restriction eq = newMultiEq(cfMetaData, 0, value1, value2);
 +        PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(eq);
 +
-         List<Composite> bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        List<Composite> bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value1, value2, EOC.START);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value1, value2, EOC.END);
 +    }
 +
 +    /**
 +     * Test '(clustering_0, clustering_1) IN ((1, 2), (2, 3))' with two clustering column
 +     */
 +    @Test
 +    public void testBoundsAsCompositesWithMultiInRestrictions()
 +    {
 +        CFMetaData cfMetaData = newCFMetaData(Sort.ASC, Sort.ASC);
 +
 +        ByteBuffer value1 = ByteBufferUtil.bytes(1);
 +        ByteBuffer value2 = ByteBufferUtil.bytes(2);
 +        ByteBuffer value3 = ByteBufferUtil.bytes(3);
 +        Restriction in = newMultiIN(cfMetaData, 0, asList(value1, value2), asList(value2, value3));
 +        PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(in);
 +
-         List<Composite> bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        List<Composite> bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(2, bounds.size());
 +        assertComposite(bounds.get(0), value1, value2, EOC.START);
 +        assertComposite(bounds.get(1), value2, value3, EOC.START);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(2, bounds.size());
 +        assertComposite(bounds.get(0), value1, value2, EOC.END);
 +        assertComposite(bounds.get(1), value2, value3, EOC.END);
 +    }
 +
 +    /**
 +     * Test multi-column slice restrictions (e.g '(clustering_0) > (1)') with only one clustering column
 +     */
 +    @Test
 +    public void testBoundsAsCompositesWithMultiSliceRestrictionsWithOneClusteringColumn()
 +    {
 +        CFMetaData cfMetaData = newCFMetaData(Sort.ASC);
 +
 +        ByteBuffer value1 = ByteBufferUtil.bytes(1);
 +        ByteBuffer value2 = ByteBufferUtil.bytes(2);
 +
 +        Restriction slice = newMultiSlice(cfMetaData, 0, Bound.START, false, value1);
 +        PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice);
 +
-         List<Composite> bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        List<Composite> bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value1, EOC.END);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertEmptyComposite(bounds.get(0));
 +
 +        slice = newMultiSlice(cfMetaData, 0, Bound.START, true, value1);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value1, EOC.NONE);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertEmptyComposite(bounds.get(0));
 +
 +        slice = newMultiSlice(cfMetaData, 0, Bound.END, true, value1);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertEmptyComposite(bounds.get(0));
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value1, EOC.END);
 +
 +        slice = newMultiSlice(cfMetaData, 0, Bound.END, false, value1);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertEmptyComposite(bounds.get(0));
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value1, EOC.START);
 +
 +        slice = newMultiSlice(cfMetaData, 0, Bound.START, false, value1);
 +        Restriction slice2 = newMultiSlice(cfMetaData, 0, Bound.END, false, value2);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value1, EOC.END);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value2, EOC.START);
 +
 +        slice = newMultiSlice(cfMetaData, 0, Bound.START, true, value1);
 +        slice2 = newMultiSlice(cfMetaData, 0, Bound.END, true, value2);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value1, EOC.NONE);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value2, EOC.END);
 +    }
 +
 +    /**
 +     * Test multi-column slice restrictions (e.g '(clustering_0) > (1)') with only one clustering column in reverse
 +     * order
 +     */
 +    @Test
 +    public void testBoundsAsCompositesWithMultiSliceRestrictionsWithOneDescendingClusteringColumn()
 +    {
 +        CFMetaData cfMetaData = newCFMetaData(Sort.DESC);
 +
 +        ByteBuffer value1 = ByteBufferUtil.bytes(1);
 +        ByteBuffer value2 = ByteBufferUtil.bytes(2);
 +
 +        Restriction slice = newMultiSlice(cfMetaData, 0, Bound.START, false, value1);
 +        PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice);
 +
-         List<Composite> bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        List<Composite> bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertEmptyComposite(bounds.get(0));
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value1, EOC.START);
 +
 +        slice = newMultiSlice(cfMetaData, 0, Bound.START, true, value1);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertEmptyComposite(bounds.get(0));
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value1, EOC.END);
 +
 +        slice = newMultiSlice(cfMetaData, 0, Bound.END, true, value1);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value1, EOC.NONE);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertEmptyComposite(bounds.get(0));
 +
 +        slice = newMultiSlice(cfMetaData, 0, Bound.END, false, value1);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value1, EOC.END);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertEmptyComposite(bounds.get(0));
 +
 +        slice = newMultiSlice(cfMetaData, 0, Bound.START, false, value1);
 +        Restriction slice2 = newMultiSlice(cfMetaData, 0, Bound.END, false, value2);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value2, EOC.END);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value1, EOC.START);
 +
 +        slice = newMultiSlice(cfMetaData, 0, Bound.START, true, value1);
 +        slice2 = newMultiSlice(cfMetaData, 0, Bound.END, true, value2);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value2, EOC.NONE);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value1, EOC.END);
 +    }
 +
 +    /**
 +     * Test multi-column slice restrictions (e.g '(clustering_0, clustering_1) > (1, 2)')
 +     */
 +    @Test
 +    public void testBoundsAsCompositesWithMultiSliceRestrictionsWithTwoClusteringColumn()
 +    {
 +        CFMetaData cfMetaData = newCFMetaData(Sort.ASC, Sort.ASC);
 +
 +        ByteBuffer value1 = ByteBufferUtil.bytes(1);
 +        ByteBuffer value2 = ByteBufferUtil.bytes(2);
 +
 +        // (clustering_0, clustering1) > (1, 2)
 +        Restriction slice = newMultiSlice(cfMetaData, 0, Bound.START, false, value1, value2);
 +        PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice);
 +
-         List<Composite> bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        List<Composite> bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value1, value2, EOC.END);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertEmptyComposite(bounds.get(0));
 +
 +        // (clustering_0, clustering1) >= (1, 2)
 +        slice = newMultiSlice(cfMetaData, 0, Bound.START, true, value1, value2);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value1, value2, EOC.NONE);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertEmptyComposite(bounds.get(0));
 +
 +        // (clustering_0, clustering1) <= (1, 2)
 +        slice = newMultiSlice(cfMetaData, 0, Bound.END, true, value1, value2);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertEmptyComposite(bounds.get(0));
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value1, value2, EOC.END);
 +
 +        // (clustering_0, clustering1) < (1, 2)
 +        slice = newMultiSlice(cfMetaData, 0, Bound.END, false, value1, value2);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertEmptyComposite(bounds.get(0));
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value1, value2, EOC.START);
 +
 +        // (clustering_0, clustering1) > (1, 2) AND (clustering_0) < (2)
 +        slice = newMultiSlice(cfMetaData, 0, Bound.START, false, value1, value2);
 +        Restriction slice2 = newMultiSlice(cfMetaData, 0, Bound.END, false, value2);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value1, value2, EOC.END);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value2, EOC.START);
 +
 +        // (clustering_0, clustering1) >= (1, 2) AND (clustering_0, clustering1) <= (2, 1)
 +        slice = newMultiSlice(cfMetaData, 0, Bound.START, true, value1, value2);
 +        slice2 = newMultiSlice(cfMetaData, 0, Bound.END, true, value2, value1);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value1, value2, EOC.NONE);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value2, value1, EOC.END);
 +    }
 +
 +    /**
 +     * Test multi-column slice restrictions with 2 descending clustering columns (e.g '(clustering_0, clustering_1) > (1, 2)')
 +     */
 +    @Test
 +    public void testBoundsAsCompositesWithMultiSliceRestrictionsWithTwoDescendingClusteringColumns()
 +    {
 +        CFMetaData cfMetaData = newCFMetaData(Sort.DESC, Sort.DESC);
 +
 +        ByteBuffer value1 = ByteBufferUtil.bytes(1);
 +        ByteBuffer value2 = ByteBufferUtil.bytes(2);
 +
 +        // (clustering_0, clustering1) > (1, 2)
 +        Restriction slice = newMultiSlice(cfMetaData, 0, Bound.START, false, value1, value2);
 +        PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice);
 +
-         List<Composite> bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        List<Composite> bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertEmptyComposite(bounds.get(0));
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value1, value2, EOC.START);
 +
 +        // (clustering_0, clustering1) >= (1, 2)
 +        slice = newMultiSlice(cfMetaData, 0, Bound.START, true, value1, value2);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertEmptyComposite(bounds.get(0));
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value1, value2, EOC.END);
 +
 +        // (clustering_0, clustering1) <= (1, 2)
 +        slice = newMultiSlice(cfMetaData, 0, Bound.END, true, value1, value2);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value1, value2, EOC.NONE);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertEmptyComposite(bounds.get(0));
 +
 +        // (clustering_0, clustering1) < (1, 2)
 +        slice = newMultiSlice(cfMetaData, 0, Bound.END, false, value1, value2);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value1, value2, EOC.END);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertEmptyComposite(bounds.get(0));
 +
 +
 +        // (clustering_0, clustering1) > (1, 2) AND (clustering_0) < (2)
 +        slice = newMultiSlice(cfMetaData, 0, Bound.START, false, value1, value2);
 +        Restriction slice2 = newMultiSlice(cfMetaData, 0, Bound.END, false, value2);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value2, EOC.END);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value1, value2, EOC.START);
 +
 +        // (clustering_0, clustering1) >= (1, 2) AND (clustering_0, clustering1) <= (2, 1)
 +        slice = newMultiSlice(cfMetaData, 0, Bound.START, true, value1, value2);
 +        slice2 = newMultiSlice(cfMetaData, 0, Bound.END, true, value2, value1);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value2, value1, EOC.NONE);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value1, value2, EOC.END);
 +    }
 +
 +    /**
 +     * Test multi-column slice restrictions with 1 descending clustering column and 1 ascending
 +     * (e.g '(clustering_0, clustering_1) > (1, 2)')
 +     */
 +    @Test
 +    public void testBoundsAsCompositesWithMultiSliceRestrictionsWithOneDescendingAndOneAscendingClusteringColumns()
 +    {
 +        CFMetaData cfMetaData = newCFMetaData(Sort.DESC, Sort.ASC);
 +
 +        ByteBuffer value1 = ByteBufferUtil.bytes(1);
 +        ByteBuffer value2 = ByteBufferUtil.bytes(2);
 +
 +        // (clustering_0, clustering1) > (1, 2)
 +        Restriction slice = newMultiSlice(cfMetaData, 0, Bound.START, false, value1, value2);
 +        PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice);
 +
-         List<Composite> bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        List<Composite> bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(2, bounds.size());
 +        assertEmptyComposite(bounds.get(0));
 +        assertComposite(bounds.get(1), value1, value2, EOC.END);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(2, bounds.size());
 +        assertComposite(bounds.get(0), value1, EOC.START);
 +        assertComposite(bounds.get(1), value1, EOC.END);
 +
 +        // (clustering_0, clustering1) >= (1, 2)
 +        slice = newMultiSlice(cfMetaData, 0, Bound.START, true, value1, value2);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(2, bounds.size());
 +        assertEmptyComposite(bounds.get(0));
 +        assertComposite(bounds.get(1), value1, value2, EOC.NONE);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(2, bounds.size());
 +        assertComposite(bounds.get(0), value1, EOC.START);
 +        assertComposite(bounds.get(1), value1, EOC.END);
 +
 +        // (clustering_0, clustering1) <= (1, 2)
 +        slice = newMultiSlice(cfMetaData, 0, Bound.END, true, value1, value2);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(2, bounds.size());
 +        assertComposite(bounds.get(0), value1, EOC.START);
 +        assertComposite(bounds.get(1), value1, EOC.END);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(2, bounds.size());
 +        assertComposite(bounds.get(0), value1, value2, EOC.END);
 +        assertEmptyComposite(bounds.get(1));
 +
 +        // (clustering_0, clustering1) < (1, 2)
 +        slice = newMultiSlice(cfMetaData, 0, Bound.END, false, value1, value2);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(2, bounds.size());
 +        assertComposite(bounds.get(0), value1, EOC.START);
 +        assertComposite(bounds.get(1), value1, EOC.END);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(2, bounds.size());
 +        assertComposite(bounds.get(0), value1, value2, EOC.START);
 +        assertEmptyComposite(bounds.get(1));
 +
 +        // (clustering_0, clustering1) > (1, 2) AND (clustering_0) < (2)
 +        slice = newMultiSlice(cfMetaData, 0, Bound.START, false, value1, value2);
 +        Restriction slice2 = newMultiSlice(cfMetaData, 0, Bound.END, false, value2);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(2, bounds.size());
 +        assertComposite(bounds.get(0), value2, EOC.END);
 +        assertComposite(bounds.get(1), value1, value2, EOC.END);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(2, bounds.size());
 +        assertComposite(bounds.get(0), value1, EOC.START);
 +        assertComposite(bounds.get(1), value1, EOC.END);
 +
 +        // (clustering_0) > (1) AND (clustering_0, clustering1) < (2, 1)
 +        slice = newMultiSlice(cfMetaData, 0, Bound.START, false, value1);
 +        slice2 = newMultiSlice(cfMetaData, 0, Bound.END, false, value2, value1);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(2, bounds.size());
 +        assertComposite(bounds.get(0), value2, EOC.START);
 +        assertComposite(bounds.get(1), value2, EOC.END);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(2, bounds.size());
 +        assertComposite(bounds.get(0), value2, value1, EOC.START);
 +        assertComposite(bounds.get(1), value1, EOC.START);
 +
 +        // (clustering_0, clustering1) >= (1, 2) AND (clustering_0, clustering1) <= (2, 1)
 +        slice = newMultiSlice(cfMetaData, 0, Bound.START, true, value1, value2);
 +        slice2 = newMultiSlice(cfMetaData, 0, Bound.END, true, value2, value1);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(3, bounds.size());
 +        assertComposite(bounds.get(0), value2, EOC.START);
 +        assertComposite(bounds.get(1), value2, EOC.END);
 +        assertComposite(bounds.get(2), value1, value2, EOC.NONE);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(3, bounds.size());
 +        assertComposite(bounds.get(0), value2, value1, EOC.END);
 +        assertComposite(bounds.get(1), value1, EOC.START);
 +        assertComposite(bounds.get(2), value1, EOC.END);
 +    }
 +
 +    /**
 +     * Test multi-column slice restrictions with 1 descending clustering column and 1 ascending
 +     * (e.g '(clustering_0, clustering_1) > (1, 2)')
 +     */
 +    @Test
 +    public void testBoundsAsCompositesWithMultiSliceRestrictionsWithOneAscendingAndOneDescendingClusteringColumns()
 +    {
 +        CFMetaData cfMetaData = newCFMetaData(Sort.ASC, Sort.DESC);
 +
 +        ByteBuffer value1 = ByteBufferUtil.bytes(1);
 +        ByteBuffer value2 = ByteBufferUtil.bytes(2);
 +
 +        // (clustering_0, clustering1) > (1, 2)
 +        Restriction slice = newMultiSlice(cfMetaData, 0, Bound.START, false, value1, value2);
 +        PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice);
 +
-         List<Composite> bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        List<Composite> bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(2, bounds.size());
 +        assertComposite(bounds.get(0), value1, EOC.START);
 +        assertComposite(bounds.get(1), value1, EOC.END);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(2, bounds.size());
 +        assertComposite(bounds.get(0), value1, value2, EOC.START);
 +        assertEmptyComposite(bounds.get(1));
 +
 +        // (clustering_0, clustering1) >= (1, 2)
 +        slice = newMultiSlice(cfMetaData, 0, Bound.START, true, value1, value2);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(2, bounds.size());
 +        assertComposite(bounds.get(0), value1, EOC.START);
 +        assertComposite(bounds.get(1), value1, EOC.END);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(2, bounds.size());
 +        assertComposite(bounds.get(0), value1, value2, EOC.END);
 +        assertEmptyComposite(bounds.get(1));
 +
 +        // (clustering_0, clustering1) <= (1, 2)
 +        slice = newMultiSlice(cfMetaData, 0, Bound.END, true, value1, value2);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(2, bounds.size());
 +        assertEmptyComposite(bounds.get(0));
 +        assertComposite(bounds.get(1), value1, value2, EOC.NONE);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(2, bounds.size());
 +        assertComposite(bounds.get(0), value1, EOC.START);
 +        assertComposite(bounds.get(1), value1, EOC.END);
 +
 +        // (clustering_0, clustering1) < (1, 2)
 +        slice = newMultiSlice(cfMetaData, 0, Bound.END, false, value1, value2);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(2, bounds.size());
 +        assertEmptyComposite(bounds.get(0));
 +        assertComposite(bounds.get(1), value1, value2, EOC.END);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(2, bounds.size());
 +        assertComposite(bounds.get(0), value1, EOC.START);
 +        assertComposite(bounds.get(1), value1, EOC.END);
 +
 +        // (clustering_0, clustering1) > (1, 2) AND (clustering_0) < (2)
 +        slice = newMultiSlice(cfMetaData, 0, Bound.START, false, value1, value2);
 +        Restriction slice2 = newMultiSlice(cfMetaData, 0, Bound.END, false, value2);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(2, bounds.size());
 +        assertComposite(bounds.get(0), value1, EOC.START);
 +        assertComposite(bounds.get(1), value1, EOC.END);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(2, bounds.size());
 +        assertComposite(bounds.get(0), value1, value2, EOC.START);
 +        assertComposite(bounds.get(1), value2, EOC.START);
 +
 +        // (clustering_0, clustering1) >= (1, 2) AND (clustering_0, clustering1) <= (2, 1)
 +        slice = newMultiSlice(cfMetaData, 0, Bound.START, true, value1, value2);
 +        slice2 = newMultiSlice(cfMetaData, 0, Bound.END, true, value2, value1);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(3, bounds.size());
 +        assertComposite(bounds.get(0), value1, EOC.START);
 +        assertComposite(bounds.get(1), value1, EOC.END);
 +        assertComposite(bounds.get(2), value2, value1, EOC.NONE);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(3, bounds.size());
 +        assertComposite(bounds.get(0), value1, value2, EOC.END);
 +        assertComposite(bounds.get(1), value2, EOC.START);
 +        assertComposite(bounds.get(2), value2, EOC.END);
 +    }
 +
 +    /**
 +     * Test multi-column slice restrictions with 2 ascending clustering column and 2 descending
 +     * (e.g '(clustering_0, clustering1, clustering_3, clustering4) > (1, 2, 3, 4)')
 +     */
 +    @Test
 +    public void testBoundsAsCompositesWithMultiSliceRestrictionsWithTwoAscendingAndTwoDescendingClusteringColumns()
 +    {
 +        CFMetaData cfMetaData = newCFMetaData(Sort.ASC, Sort.ASC, Sort.DESC, Sort.DESC);
 +
 +        ByteBuffer value1 = ByteBufferUtil.bytes(1);
 +        ByteBuffer value2 = ByteBufferUtil.bytes(2);
 +        ByteBuffer value3 = ByteBufferUtil.bytes(3);
 +        ByteBuffer value4 = ByteBufferUtil.bytes(4);
 +
 +        // (clustering_0, clustering1, clustering_2, clustering_3) > (1, 2, 3, 4)
 +        Restriction slice = newMultiSlice(cfMetaData, 0, Bound.START, false, value1, value2, value3, value4);
 +        PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice);
 +
-         List<Composite> bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        List<Composite> bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(2, bounds.size());
 +        assertComposite(bounds.get(0), value1, value2, EOC.START);
 +        assertComposite(bounds.get(1), value1, value2, EOC.END);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(2, bounds.size());
 +        assertComposite(bounds.get(0), value1, value2, value3, value4, EOC.START);
 +        assertEmptyComposite(bounds.get(1));
 +
 +        // clustering_0 = 1 AND (clustering_1, clustering_2, clustering_3) > (2, 3, 4)
 +        Restriction eq = newSingleEq(cfMetaData, 0, value1);
 +        slice = newMultiSlice(cfMetaData, 1, Bound.START, false, value2, value3, value4);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice);
 +        restrictions = restrictions.mergeWith(eq);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(2, bounds.size());
 +        assertComposite(bounds.get(0), value1, value2, EOC.START);
 +        assertComposite(bounds.get(1), value1, value2, EOC.END);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(2, bounds.size());
 +        assertComposite(bounds.get(0), value1, value2, value3, value4, EOC.START);
 +        assertComposite(bounds.get(1), value1, EOC.END);
 +
 +        // clustering_0 = 1 AND (clustering_1, clustering_2, clustering_3) > (2, 3, 4)
 +        Restriction in = newSingleIN(cfMetaData, 0, value1, value2);
 +        slice = newMultiSlice(cfMetaData, 1, Bound.START, false, value2, value3, value4);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice);
 +        restrictions = restrictions.mergeWith(in);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(4, bounds.size());
 +        assertComposite(bounds.get(0), value1, value2, EOC.START);
 +        assertComposite(bounds.get(1), value1, value2, EOC.END);
 +        assertComposite(bounds.get(2), value2, value2, EOC.START);
 +        assertComposite(bounds.get(3), value2, value2, EOC.END);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(4, bounds.size());
 +        assertComposite(bounds.get(0), value1, value2, value3, value4, EOC.START);
 +        assertComposite(bounds.get(1), value1, EOC.END);
 +        assertComposite(bounds.get(2), value2, value2, value3, value4, EOC.START);
 +        assertComposite(bounds.get(3), value2, EOC.END);
 +
 +        // (clustering_0, clustering1) >= (1, 2)
 +        slice = newMultiSlice(cfMetaData, 0, Bound.START, true, value1, value2);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value1, value2, EOC.NONE);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertEmptyComposite(bounds.get(0));
 +
 +        // (clustering_0, clustering1, clustering_2, clustering_3) >= (1, 2, 3, 4)
 +        slice = newMultiSlice(cfMetaData, 0, Bound.START, true, value1, value2, value3, value4);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(2, bounds.size());
 +        assertComposite(bounds.get(0), value1, value2, EOC.START);
 +        assertComposite(bounds.get(1), value1, value2, EOC.END);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(2, bounds.size());
 +        assertComposite(bounds.get(0), value1, value2, value3, value4, EOC.END);
 +        assertEmptyComposite(bounds.get(1));
 +
 +        // (clustering_0, clustering1, clustering_2, clustering_3) <= (1, 2, 3, 4)
 +        slice = newMultiSlice(cfMetaData, 0, Bound.END, true, value1, value2, value3, value4);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(2, bounds.size());
 +        assertEmptyComposite(bounds.get(0));
 +        assertComposite(bounds.get(1), value1, value2, value3, value4, EOC.NONE);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(2, bounds.size());
 +        assertComposite(bounds.get(0), value1, value2, EOC.START);
 +        assertComposite(bounds.get(1), value1, value2, EOC.END);
 +
 +        // (clustering_0, clustering1, clustering_2, clustering_3) < (1, 2, 3, 4)
 +        slice = newMultiSlice(cfMetaData, 0, Bound.END, false, value1, value2, value3, value4);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(2, bounds.size());
 +        assertEmptyComposite(bounds.get(0));
 +        assertComposite(bounds.get(1), value1, value2, value3, value4, EOC.END);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(2, bounds.size());
 +        assertComposite(bounds.get(0), value1, value2, EOC.START);
 +        assertComposite(bounds.get(1), value1, value2, EOC.END);
 +
 +        // (clustering_0, clustering1, clustering_2, clustering_3) > (1, 2, 3, 4) AND (clustering_0, clustering_1) < (2, 3)
 +        slice = newMultiSlice(cfMetaData, 0, Bound.START, false, value1, value2, value3, value4);
 +        Restriction slice2 = newMultiSlice(cfMetaData, 0, Bound.END, false, value2, value3);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(2, bounds.size());
 +        assertComposite(bounds.get(0), value1, value2, EOC.START);
 +        assertComposite(bounds.get(1), value1, value2, EOC.END);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(2, bounds.size());
 +        assertComposite(bounds.get(0), value1, value2, value3, value4, EOC.START);
 +        assertComposite(bounds.get(1), value2, value3, EOC.START);
 +
 +        // (clustering_0, clustering1, clustering_2, clustering_3) >= (1, 2, 3, 4) AND (clustering_0, clustering1, clustering_2, clustering_3) <= (4, 3, 2, 1)
 +        slice = newMultiSlice(cfMetaData, 0, Bound.START, true, value1, value2, value3, value4);
 +        slice2 = newMultiSlice(cfMetaData, 0, Bound.END, true, value4, value3, value2, value1);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(3, bounds.size());
 +        assertComposite(bounds.get(0), value1, value2,  EOC.START);
 +        assertComposite(bounds.get(1), value1, value2, EOC.END);
 +        assertComposite(bounds.get(2), value4, value3, value2, value1, EOC.NONE);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(3, bounds.size());
 +        assertComposite(bounds.get(0), value1, value2, value3, value4, EOC.END);
 +        assertComposite(bounds.get(1), value4, value3, EOC.START);
 +        assertComposite(bounds.get(2), value4, value3, EOC.END);
 +    }
 +
 +    /**
 +     * Test multi-column slice restrictions with ascending, descending, ascending and descending columns
 +     * (e.g '(clustering_0, clustering1, clustering_3, clustering4) > (1, 2, 3, 4)')
 +     */
 +    @Test
 +    public void testBoundsAsCompositesWithMultiSliceRestrictionsMixingAscendingDescendingClusteringColumns()
 +    {
 +        CFMetaData cfMetaData = newCFMetaData(Sort.ASC, Sort.DESC, Sort.ASC, Sort.DESC);
 +
 +        ByteBuffer value1 = ByteBufferUtil.bytes(1);
 +        ByteBuffer value2 = ByteBufferUtil.bytes(2);
 +        ByteBuffer value3 = ByteBufferUtil.bytes(3);
 +        ByteBuffer value4 = ByteBufferUtil.bytes(4);
 +
 +        // (clustering_0, clustering1, clustering_2, clustering_3) > (1, 2, 3, 4)
 +        Restriction slice = newMultiSlice(cfMetaData, 0, Bound.START, false, value1, value2, value3, value4);
 +        PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice);
 +
-         List<Composite> bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        List<Composite> bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(4, bounds.size());
 +        assertComposite(bounds.get(0), value1, EOC.START);
 +        assertComposite(bounds.get(1), value1, value2, value3, EOC.START);
 +        assertComposite(bounds.get(2), value1, value2, value3, EOC.END);
 +        assertComposite(bounds.get(3), value1, EOC.END);
 +
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(4, bounds.size());
 +        assertComposite(bounds.get(0), value1, value2, EOC.START);
 +        assertComposite(bounds.get(1), value1, value2, value3, value4, EOC.START);
 +        assertComposite(bounds.get(2), value1, value2, EOC.END);
 +        assertEmptyComposite(bounds.get(3));
 +
 +        // clustering_0 = 1 AND (clustering_1, clustering_2, clustering_3) > (2, 3, 4)
 +        Restriction eq = newSingleEq(cfMetaData, 0, value1);
 +        slice = newMultiSlice(cfMetaData, 1, Bound.START, false, value2, value3, value4);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice);
 +        restrictions = restrictions.mergeWith(eq);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(3, bounds.size());
 +        assertComposite(bounds.get(0), value1, EOC.START);
 +        assertComposite(bounds.get(1), value1, value2, value3, EOC.START);
 +        assertComposite(bounds.get(2), value1, value2, value3, EOC.END);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(3, bounds.size());
 +        assertComposite(bounds.get(0), value1, value2, EOC.START);
 +        assertComposite(bounds.get(1), value1, value2, value3, value4, EOC.START);
 +        assertComposite(bounds.get(2), value1, value2, EOC.END);
 +
 +        // (clustering_0, clustering1) >= (1, 2)
 +        slice = newMultiSlice(cfMetaData, 0, Bound.START, true, value1, value2);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(2, bounds.size());
 +        assertComposite(bounds.get(0), value1, EOC.START);
 +        assertComposite(bounds.get(1), value1, EOC.END);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(2, bounds.size());
 +        assertComposite(bounds.get(0), value1, value2, EOC.END);
 +        assertEmptyComposite(bounds.get(1));
 +
 +        // (clustering_0, clustering1, clustering_2, clustering_3) >= (1, 2, 3, 4)
 +        slice = newMultiSlice(cfMetaData, 0, Bound.START, true, value1, value2, value3, value4);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(4, bounds.size());
 +        assertComposite(bounds.get(0), value1, EOC.START);
 +        assertComposite(bounds.get(1), value1, value2, value3, EOC.START);
 +        assertComposite(bounds.get(2), value1, value2, value3, EOC.END);
 +        assertComposite(bounds.get(3), value1, EOC.END);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(4, bounds.size());
 +        assertComposite(bounds.get(0), value1, value2, EOC.START);
 +        assertComposite(bounds.get(1), value1, value2, value3, value4, EOC.END);
 +        assertComposite(bounds.get(2), value1, value2, EOC.END);
 +        assertEmptyComposite(bounds.get(3));
 +
 +
 +        // (clustering_0, clustering1, clustering_2, clustering_3) <= (1, 2, 3, 4)
 +        slice = newMultiSlice(cfMetaData, 0, Bound.END, true, value1, value2, value3, value4);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(4, bounds.size());
 +        assertEmptyComposite(bounds.get(0));
 +        assertComposite(bounds.get(1), value1, value2, EOC.START);
 +        assertComposite(bounds.get(2), value1, value2, value3, value4, EOC.NONE);
 +        assertComposite(bounds.get(3), value1, value2, EOC.END);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(4, bounds.size());
 +        assertComposite(bounds.get(0), value1, EOC.START);
 +        assertComposite(bounds.get(1), value1, value2, value3, EOC.START);
 +        assertComposite(bounds.get(2), value1, value2, value3, EOC.END);
 +        assertComposite(bounds.get(3), value1, EOC.END);
 +
 +        // (clustering_0, clustering1, clustering_2, clustering_3) < (1, 2, 3, 4)
 +        slice = newMultiSlice(cfMetaData, 0, Bound.END, false, value1, value2, value3, value4);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(4, bounds.size());
 +        assertEmptyComposite(bounds.get(0));
 +        assertComposite(bounds.get(1), value1, value2, EOC.START);
 +        assertComposite(bounds.get(2), value1, value2, value3, value4, EOC.END);
 +        assertComposite(bounds.get(3), value1, value2, EOC.END);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(4, bounds.size());
 +        assertComposite(bounds.get(0), value1, EOC.START);
 +        assertComposite(bounds.get(1), value1, value2, value3, EOC.START);
 +        assertComposite(bounds.get(2), value1, value2, value3, EOC.END);
 +        assertComposite(bounds.get(3), value1, EOC.END);
 +
 +        // (clustering_0, clustering1, clustering_2, clustering_3) > (1, 2, 3, 4) AND (clustering_0, clustering_1) < (2, 3)
 +        slice = newMultiSlice(cfMetaData, 0, Bound.START, false, value1, value2, value3, value4);
 +        Restriction slice2 = newMultiSlice(cfMetaData, 0, Bound.END, false, value2, value3);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(5, bounds.size());
 +        assertComposite(bounds.get(0), value1, EOC.START);
 +        assertComposite(bounds.get(1), value1, value2, value3, EOC.START);
 +        assertComposite(bounds.get(2), value1, value2, value3, EOC.END);
 +        assertComposite(bounds.get(3), value1, EOC.END);
 +        assertComposite(bounds.get(4), value2, value3, EOC.END);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(5, bounds.size());
 +        assertComposite(bounds.get(0), value1, value2, EOC.START);
 +        assertComposite(bounds.get(1), value1, value2, value3, value4, EOC.START);
 +        assertComposite(bounds.get(2), value1, value2, EOC.END);
 +        assertComposite(bounds.get(3), value2, EOC.START);
 +        assertComposite(bounds.get(4), value2, EOC.END);
 +
 +        // (clustering_0, clustering1, clustering_2, clustering_3) >= (1, 2, 3, 4) AND (clustering_0, clustering1, clustering_2, clustering_3) <= (4, 3, 2, 1)
 +        slice = newMultiSlice(cfMetaData, 0, Bound.START, true, value1, value2, value3, value4);
 +        slice2 = newMultiSlice(cfMetaData, 0, Bound.END, true, value4, value3, value2, value1);
 +        restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
 +
-         bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(7, bounds.size());
 +        assertComposite(bounds.get(0), value1, EOC.START);
 +        assertComposite(bounds.get(1), value1, value2, value3, EOC.START);
 +        assertComposite(bounds.get(2), value1, value2, value3, EOC.END);
 +        assertComposite(bounds.get(3), value1, EOC.END);
 +        assertComposite(bounds.get(4), value4, value3, EOC.START);
 +        assertComposite(bounds.get(5), value4, value3, value2, value1, EOC.NONE);
 +        assertComposite(bounds.get(6), value4, value3, EOC.END);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComposites(cfMetaData, Bound.END, QueryOptions.DEFAULT);
 +        assertEquals(7, bounds.size());
 +        assertComposite(bounds.get(0), value1, value2, EOC.START);
 +        assertComposite(bounds.get(1), value1, value2, value3, value4, EOC.END);
 +        assertComposite(bounds.get(2), value1, value2, EOC.END);
 +        assertComposite(bounds.get(3), value4, EOC.START);
 +        assertComposite(bounds.get(4), value4, value3, value2, EOC.START);
 +        assertComposite(bounds.get(5), value4, value3, value2, EOC.END);
 +        assertComposite(bounds.get(6), value4, EOC.END);
 +    }
 +
 +    /**
 +     * Test mixing single and multi equals restrictions (e.g. clustering_0 = 1 AND (clustering_1, clustering_2) = (2, 3))
 +     */
 +    @Test
 +    public void testBoundsAsCompositesWithSingleEqAndMultiEqRestrictions()
 +    {
 +        CFMetaData cfMetaData = newCFMetaData(Sort.ASC, Sort.ASC, Sort.ASC, Sort.ASC);
 +
 +        ByteBuffer value1 = ByteBufferUtil.bytes(1);
 +        ByteBuffer value2 = ByteBufferUtil.bytes(2);
 +        ByteBuffer value3 = ByteBufferUtil.bytes(3);
 +        ByteBuffer value4 = ByteBufferUtil.bytes(4);
 +
 +        // clustering_0 = 1 AND (clustering_1, clustering_2) = (2, 3)
 +        Restriction singleEq = newSingleEq(cfMetaData, 0, value1);
 +        Restriction multiEq = newMultiEq(cfMetaData, 1, value2, value3);
 +        PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
 +        restrictions = restrictions.mergeWith(singleEq).mergeWith(multiEq);
 +
-         List<Composite> bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++        List<Composite> bounds = restrictions.boundsAsComposites(cfMetaData, Bound.START, QueryOptions.DEFAULT);
 +        assertEquals(1, bounds.size());
 +        assertComposite(bounds.get(0), value1, value2, value3, EOC.START);
 +
-         bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++        bounds = restrictions.boundsAsComp

<TRUNCATED>