You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by gg...@apache.org on 2021/11/30 21:11:31 UTC

[commons-lang] branch master updated: Add FluentBitSet.

This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-lang.git


The following commit(s) were added to refs/heads/master by this push:
     new 6e1c336  Add FluentBitSet.
6e1c336 is described below

commit 6e1c3366752928019080537fb909cd7dbd7ffb2f
Author: Gary Gregory <ga...@gmail.com>
AuthorDate: Tue Nov 30 16:11:27 2021 -0500

    Add FluentBitSet.
---
 src/changes/changes.xml                            |    1 +
 .../apache/commons/lang3/util/FluentBitSet.java    |  606 +++++++
 .../apache/commons/lang3/util/package-info.java    |   22 +
 .../commons/lang3/util/FluentBitSetTest.java       | 1827 ++++++++++++++++++++
 4 files changed, 2456 insertions(+)

diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index b3c8ae1..d6e9072 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -103,6 +103,7 @@ The <action> type attribute can be add,update,fix,remove.
     <action                   type="add" dev="ggregory" due-to="Gary Gregory">Add Streams.failableStream(Collection) and deprecate misnamed stream(Collection).</action>
     <action                   type="add" dev="ggregory" due-to="Gary Gregory">Add Streams.failableStream(Stream) and deprecate misnamed stream(Stream).</action>
     <action                   type="add" dev="ggregory" due-to="Maxwell Cody, Gary Gregory">Add EnumUtils.getEnumMap(Class, Function). #730</action>
+    <action                   type="add" dev="ggregory" due-to="Gary Gregory">Add FluentBitSet.</action>
     <!-- UPDATE -->
     <action                   type="update" dev="ggregory" due-to="Dependabot, Gary Gregory">Bump spotbugs-maven-plugin from 4.2.0 to 4.5.0.0 #735, #808, #822, #834.</action>
     <action                   type="update" dev="ggregory" due-to="Dependabot, XenoAmess">Bump actions/cache from v2.1.4 to v2.1.7 #742, #752, #764, #833.</action>
diff --git a/src/main/java/org/apache/commons/lang3/util/FluentBitSet.java b/src/main/java/org/apache/commons/lang3/util/FluentBitSet.java
new file mode 100644
index 0000000..2b41f5e
--- /dev/null
+++ b/src/main/java/org/apache/commons/lang3/util/FluentBitSet.java
@@ -0,0 +1,606 @@
+/*
+ * 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.commons.lang3.util;
+
+import java.io.Serializable;
+import java.util.BitSet;
+import java.util.Objects;
+import java.util.stream.IntStream;
+
+/**
+ * A fluent {@link BitSet} with additional operations.
+ * <p>
+ * Originally from Apache Commons VFS with more added to act as a fluent replacement for {@link java.util.BitSet}.
+ * </p>
+ * @since 3.13.0
+ */
+public final class FluentBitSet implements Cloneable, Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private final BitSet bitSet;
+
+    /**
+     * Creates a new bit set. All bits are initially {@code false}.
+     */
+    public FluentBitSet() {
+        this(new BitSet());
+    }
+
+    /**
+     * Creates a new instance for the given bit set.
+     *
+     * @param set The bit set to wrap.
+     */
+    public FluentBitSet(final BitSet set) {
+        this.bitSet = Objects.requireNonNull(set, "set");
+    }
+
+    /**
+     * Creates a bit set whose initial size is large enough to explicitly represent bits with indices in the range {@code 0}
+     * through {@code nbits-1}. All bits are initially {@code false}.
+     *
+     * @param nbits the initial size of the bit set.
+     * @throws NegativeArraySizeException if the specified initial size is negative.
+     */
+    public FluentBitSet(final int nbits) {
+        this(new BitSet(nbits));
+    }
+
+    /**
+     * Performs a logical <b>AND</b> of this target bit set with the argument bit set. This bit set is modified so that each
+     * bit in it has the value {@code true} if and only if it both initially had the value {@code true} and the
+     * corresponding bit in the bit set argument also had the value {@code true}.
+     *
+     * @param set a bit set.
+     * @return this.
+     */
+    public FluentBitSet and(final BitSet set) {
+        bitSet.and(set);
+        return this;
+    }
+
+    /**
+     * Performs a logical <b>AND</b> of this target bit set with the argument bit set. This bit set is modified so that each
+     * bit in it has the value {@code true} if and only if it both initially had the value {@code true} and the
+     * corresponding bit in the bit set argument also had the value {@code true}.
+     *
+     * @param set a bit set.
+     * @return this.
+     */
+    public FluentBitSet and(final FluentBitSet set) {
+        bitSet.and(set.bitSet);
+        return this;
+    }
+
+    /**
+     * Clears all of the bits in this {@code BitSet} whose corresponding bit is set in the specified {@code BitSet}.
+     *
+     * @param set the {@code BitSet} with which to mask this {@code BitSet}.
+     * @return this.
+     */
+    public FluentBitSet andNot(final BitSet set) {
+        bitSet.andNot(set);
+        return this;
+    }
+
+    /**
+     * Clears all of the bits in this {@code BitSet} whose corresponding bit is set in the specified {@code BitSet}.
+     *
+     * @param set the {@code BitSet} with which to mask this {@code BitSet}.
+     * @return this.
+     */
+    public FluentBitSet andNot(final FluentBitSet set) {
+        this.bitSet.andNot(set.bitSet);
+        return this;
+    }
+
+    /**
+     * Gets the wrapped bit set.
+     *
+     * @return the wrapped bit set.
+     */
+    public BitSet bitSet() {
+        return bitSet;
+    }
+
+    /**
+     * Returns the number of bits set to {@code true} in this {@code BitSet}.
+     *
+     * @return the number of bits set to {@code true} in this {@code BitSet}.
+     */
+    public int cardinality() {
+        return bitSet.cardinality();
+    }
+
+    /**
+     * Sets all of the bits in this BitSet to {@code false}.
+     *
+     * @return this.
+     */
+    public FluentBitSet clear() {
+        bitSet.clear();
+        return this;
+    }
+
+    /**
+     * Sets the bits specified by the indexes to {@code false}.
+     *
+     * @param bitIndexArray the index of the bit to be cleared.
+     * @throws IndexOutOfBoundsException if the specified index is negative.
+     * @return this.
+     */
+    public FluentBitSet clear(final int... bitIndexArray) {
+        for (final int e : bitIndexArray) {
+            this.bitSet.clear(e);
+        }
+        return this;
+    }
+
+    /**
+     * Sets the bit specified by the index to {@code false}.
+     *
+     * @param bitIndex the index of the bit to be cleared.
+     * @throws IndexOutOfBoundsException if the specified index is negative.
+     * @return this.
+     */
+    public FluentBitSet clear(final int bitIndex) {
+        bitSet.clear(bitIndex);
+        return this;
+    }
+
+    /**
+     * Sets the bits from the specified {@code fromIndex} (inclusive) to the specified {@code toIndex} (exclusive) to
+     * {@code false}.
+     *
+     * @param fromIndex index of the first bit to be cleared.
+     * @param toIndex index after the last bit to be cleared.
+     * @throws IndexOutOfBoundsException if {@code fromIndex} is negative, or {@code toIndex} is negative, or
+     *         {@code fromIndex} is larger than {@code toIndex}.
+     * @return this.
+     */
+    public FluentBitSet clear(final int fromIndex, final int toIndex) {
+        bitSet.clear(fromIndex, toIndex);
+        return this;
+    }
+
+    /**
+     * Cloning this {@code BitSet} produces a new {@code BitSet} that is equal to it. The clone of the bit set is another
+     * bit set that has exactly the same bits set to {@code true} as this bit set.
+     *
+     * @return a clone of this bit set
+     * @see #size()
+     */
+    @Override
+    public Object clone() {
+        return new FluentBitSet((BitSet) bitSet.clone());
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!(obj instanceof FluentBitSet)) {
+            return false;
+        }
+        FluentBitSet other = (FluentBitSet) obj;
+        return Objects.equals(bitSet, other.bitSet);
+    }
+
+    /**
+     * Sets the bit at the specified index to the complement of its current value.
+     *
+     * @param bitIndex the index of the bit to flip.
+     * @throws IndexOutOfBoundsException if the specified index is negative.
+     * @return this.
+     */
+    public FluentBitSet flip(final int bitIndex) {
+        bitSet.flip(bitIndex);
+        return this;
+    }
+
+    /**
+     * Sets each bit from the specified {@code fromIndex} (inclusive) to the specified {@code toIndex} (exclusive) to the
+     * complement of its current value.
+     *
+     * @param fromIndex index of the first bit to flip.
+     * @param toIndex index after the last bit to flip.
+     * @throws IndexOutOfBoundsException if {@code fromIndex} is negative, or {@code toIndex} is negative, or
+     *         {@code fromIndex} is larger than {@code toIndex}.
+     * @return this.
+     */
+    public FluentBitSet flip(final int fromIndex, final int toIndex) {
+        bitSet.flip(fromIndex, toIndex);
+        return this;
+    }
+
+    /**
+     * Returns the value of the bit with the specified index. The value is {@code true} if the bit with the index
+     * {@code bitIndex} is currently set in this {@code BitSet}; otherwise, the result is {@code false}.
+     *
+     * @param bitIndex the bit index.
+     * @return the value of the bit with the specified index.
+     * @throws IndexOutOfBoundsException if the specified index is negative.
+     */
+    public boolean get(final int bitIndex) {
+        return bitSet.get(bitIndex);
+    }
+
+    /**
+     * Returns a new {@code BitSet} composed of bits from this {@code BitSet} from {@code fromIndex} (inclusive) to
+     * {@code toIndex} (exclusive).
+     *
+     * @param fromIndex index of the first bit to include.
+     * @param toIndex index after the last bit to include.
+     * @return a new {@code BitSet} from a range of this {@code BitSet}.
+     * @throws IndexOutOfBoundsException if {@code fromIndex} is negative, or {@code toIndex} is negative, or
+     *         {@code fromIndex} is larger than {@code toIndex}.
+     */
+    public FluentBitSet get(final int fromIndex, final int toIndex) {
+        return new FluentBitSet(bitSet.get(fromIndex, toIndex));
+    }
+
+    @Override
+    public int hashCode() {
+        return bitSet.hashCode();
+    }
+
+    /**
+     * Returns true if the specified {@code BitSet} has any bits set to {@code true} that are also set to {@code true} in
+     * this {@code BitSet}.
+     *
+     * @param set {@code BitSet} to intersect with.
+     * @return boolean indicating whether this {@code BitSet} intersects the specified {@code BitSet}.
+     */
+    public boolean intersects(final BitSet set) {
+        return bitSet.intersects(set);
+    }
+
+    /**
+     * Returns true if the specified {@code BitSet} has any bits set to {@code true} that are also set to {@code true} in
+     * this {@code BitSet}.
+     *
+     * @param set {@code BitSet} to intersect with.
+     * @return boolean indicating whether this {@code BitSet} intersects the specified {@code BitSet}.
+     */
+    public boolean intersects(final FluentBitSet set) {
+        return bitSet.intersects(set.bitSet);
+    }
+
+    /**
+     * Returns true if this {@code BitSet} contains no bits that are set to {@code true}.
+     *
+     * @return boolean indicating whether this {@code BitSet} is empty.
+     */
+    public boolean isEmpty() {
+        return bitSet.isEmpty();
+    }
+
+    /**
+     * Returns the "logical size" of this {@code BitSet}: the index of the highest set bit in the {@code BitSet} plus one.
+     * Returns zero if the {@code BitSet} contains no set bits.
+     *
+     * @return the logical size of this {@code BitSet}.
+     */
+    public int length() {
+        return bitSet.length();
+    }
+
+    /**
+     * Returns the index of the first bit that is set to {@code false} that occurs on or after the specified starting index.
+     *
+     * @param fromIndex the index to start checking from (inclusive).
+     * @return the index of the next clear bit.
+     * @throws IndexOutOfBoundsException if the specified index is negative.
+     */
+    public int nextClearBit(final int fromIndex) {
+        return bitSet.nextClearBit(fromIndex);
+    }
+
+    /**
+     * Returns the index of the first bit that is set to {@code true} that occurs on or after the specified starting index.
+     * If no such bit exists then {@code -1} is returned.
+     * <p>
+     * To iterate over the {@code true} bits in a {@code BitSet}, use the following loop:
+     * </p>
+     *
+     * <pre>
+     * {@code
+     * for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i+1)) {
+     *     // operate on index i here
+     *     if (i == Integer.MAX_VALUE) {
+     *         break; // or (i+1) would overflow
+     *     }
+     * }}
+     * </pre>
+     *
+     * @param fromIndex the index to start checking from (inclusive).
+     * @return the index of the next set bit, or {@code -1} if there is no such bit.
+     * @throws IndexOutOfBoundsException if the specified index is negative.
+     */
+    public int nextSetBit(final int fromIndex) {
+        return bitSet.nextSetBit(fromIndex);
+    }
+
+    /**
+     * Performs a logical <b>OR</b> of this bit set with the bit set argument. This bit set is modified so that a bit in it
+     * has the value {@code true} if and only if it either already had the value {@code true} or the corresponding bit in
+     * the bit set argument has the value {@code true}.
+     *
+     * @param set a bit set.
+     * @return this.
+     */
+    public FluentBitSet or(final BitSet set) {
+        bitSet.or(set);
+        return this;
+    }
+
+    /**
+     * Performs a logical <b>OR</b> of this bit set with the bit set arguments. This bit set is modified so that a bit in it
+     * has the value {@code true} if and only if it either already had the value {@code true} or the corresponding bit in
+     * the bit set argument has the value {@code true}.
+     *
+     * @param set a bit set.
+     * @return this.
+     */
+    public FluentBitSet or(final FluentBitSet... set) {
+        for (final FluentBitSet e : set) {
+            this.bitSet.or(e.bitSet);
+        }
+        return this;
+    }
+
+    /**
+     * Performs a logical <b>OR</b> of this bit set with the bit set argument. This bit set is modified so that a bit in it
+     * has the value {@code true} if and only if it either already had the value {@code true} or the corresponding bit in
+     * the bit set argument has the value {@code true}.
+     *
+     * @param set a bit set.
+     * @return this.
+     */
+    public FluentBitSet or(final FluentBitSet set) {
+        this.bitSet.or(set.bitSet);
+        return this;
+    }
+
+    /**
+     * Returns the index of the nearest bit that is set to {@code false} that occurs on or before the specified starting
+     * index. If no such bit exists, or if {@code -1} is given as the starting index, then {@code -1} is returned.
+     *
+     * @param fromIndex the index to start checking from (inclusive).
+     * @return the index of the previous clear bit, or {@code -1} if there is no such bit.
+     * @throws IndexOutOfBoundsException if the specified index is less than {@code -1}.
+     */
+    public int previousClearBit(final int fromIndex) {
+        return bitSet.previousClearBit(fromIndex);
+    }
+
+    /**
+     * Returns the index of the nearest bit that is set to {@code true} that occurs on or before the specified starting
+     * index. If no such bit exists, or if {@code -1} is given as the starting index, then {@code -1} is returned.
+     *
+     * <p>
+     * To iterate over the {@code true} bits in a {@code BitSet}, use the following loop:
+     *
+     * <pre>
+     *  {@code
+     * for (int i = bs.length(); (i = bs.previousSetBit(i-1)) >= 0; ) {
+     *     // operate on index i here
+     * }}
+     * </pre>
+     *
+     * @param fromIndex the index to start checking from (inclusive)
+     * @return the index of the previous set bit, or {@code -1} if there is no such bit
+     * @throws IndexOutOfBoundsException if the specified index is less than {@code -1}
+     */
+    public int previousSetBit(final int fromIndex) {
+        return bitSet.previousSetBit(fromIndex);
+    }
+
+    /**
+     * Sets the bit at the specified indexes to {@code true}.
+     *
+     * @param bitIndexArray a bit index array.
+     * @throws IndexOutOfBoundsException if the specified index is negative.
+     * @return this.
+     */
+    public FluentBitSet set(final int... bitIndexArray) {
+        for (final int e : bitIndexArray) {
+            bitSet.set(e);
+        }
+        return this;
+    }
+
+    /**
+     * Sets the bit at the specified index to {@code true}.
+     *
+     * @param bitIndex a bit index
+     * @throws IndexOutOfBoundsException if the specified index is negative
+     * @return this.
+     */
+    public FluentBitSet set(final int bitIndex) {
+        bitSet.set(bitIndex);
+        return this;
+    }
+
+    /**
+     * Sets the bit at the specified index to the specified value.
+     *
+     * @param bitIndex a bit index.
+     * @param value a boolean value to set.
+     * @throws IndexOutOfBoundsException if the specified index is negative.
+     * @return this.
+     */
+    public FluentBitSet set(final int bitIndex, final boolean value) {
+        bitSet.set(bitIndex, value);
+        return this;
+    }
+
+    /**
+     * Sets the bits from the specified {@code fromIndex} (inclusive) to the specified {@code toIndex} (exclusive) to
+     * {@code true}.
+     *
+     * @param fromIndex index of the first bit to be set.
+     * @param toIndex index after the last bit to be set.
+     * @throws IndexOutOfBoundsException if {@code fromIndex} is negative, or {@code toIndex} is negative, or
+     *         {@code fromIndex} is larger than {@code toIndex}.
+     * @return this.
+     */
+    public FluentBitSet set(final int fromIndex, final int toIndex) {
+        bitSet.set(fromIndex, toIndex);
+        return this;
+    }
+
+    /**
+     * Sets the bits from the specified {@code fromIndex} (inclusive) to the specified {@code toIndex} (exclusive) to the
+     * specified value.
+     *
+     * @param fromIndex index of the first bit to be set.
+     * @param toIndex index after the last bit to be set.
+     * @param value value to set the selected bits to.
+     * @throws IndexOutOfBoundsException if {@code fromIndex} is negative, or {@code toIndex} is negative, or
+     *         {@code fromIndex} is larger than {@code toIndex}.
+     * @return this.
+     */
+    public FluentBitSet set(final int fromIndex, final int toIndex, final boolean value) {
+        bitSet.set(fromIndex, toIndex, value);
+        return this;
+    }
+
+    /**
+     * Sets the bits from the specified {@code fromIndex} (inclusive) to the specified {@code toIndex} (exclusive) to
+     * {@code true}.
+     *
+     * @param fromIndex index of the first bit to be set
+     * @param toIndex index of the last bit to be set
+     * @throws IndexOutOfBoundsException if {@code fromIndex} is negative, or {@code toIndex} is negative, or
+     *         {@code fromIndex} is larger than {@code toIndex}
+     * @return this.
+     */
+    public FluentBitSet setInclusive(final int fromIndex, final int toIndex) {
+        bitSet.set(fromIndex, toIndex + 1);
+        return this;
+    }
+
+    /**
+     * Returns the number of bits of space actually in use by this {@code BitSet} to represent bit values. The maximum
+     * element in the set is the size - 1st element.
+     *
+     * @return the number of bits currently in this bit set.
+     */
+    public int size() {
+        return bitSet.size();
+    }
+
+    /**
+     * Returns a stream of indices for which this {@code BitSet} contains a bit in the set state. The indices are returned
+     * in order, from lowest to highest. The size of the stream is the number of bits in the set state, equal to the value
+     * returned by the {@link #cardinality()} method.
+     *
+     * <p>
+     * The bit set must remain constant during the execution of the terminal stream operation. Otherwise, the result of the
+     * terminal stream operation is undefined.
+     * </p>
+     *
+     * @return a stream of integers representing set indices.
+     * @since 1.8
+     */
+    public IntStream stream() {
+        return bitSet.stream();
+    }
+
+    /**
+     * Returns a new byte array containing all the bits in this bit set.
+     *
+     * <p>
+     * More precisely, if:
+     * </p>
+     * <ol>
+     * <li>{@code byte[] bytes = s.toByteArray();}</li>
+     * <li>then {@code bytes.length == (s.length()+7)/8} and</li>
+     * <li>{@code s.get(n) == ((bytes[n/8] & (1<<(n%8))) != 0)}</li>
+     * <li>for all {@code n < 8 * bytes.length}.</li>
+     * </ol>
+     *
+     * @return a byte array containing a little-endian representation of all the bits in this bit set
+     */
+    public byte[] toByteArray() {
+        return bitSet.toByteArray();
+    }
+
+    /**
+     * Returns a new byte array containing all the bits in this bit set.
+     *
+     * <p>
+     * More precisely, if:
+     * </p>
+     * <ol>
+     * <li>{@code long[] longs = s.toLongArray();}</li>
+     * <li>then {@code longs.length == (s.length()+63)/64} and</li>
+     * <li>{@code s.get(n) == ((longs[n/64] & (1L<<(n%64))) != 0)}</li>
+     * <li>for all {@code n < 64 * longs.length}.</li>
+     * </ol>
+     *
+     * @return a byte array containing a little-endian representation of all the bits in this bit set
+     */
+    public long[] toLongArray() {
+        return bitSet.toLongArray();
+    }
+
+    @Override
+    public String toString() {
+        return bitSet.toString();
+    }
+
+    /**
+     * Performs a logical <b>XOR</b> of this bit set with the bit set argument. This bit set is modified so that a bit in it
+     * has the value {@code true} if and only if one of the following statements holds:
+     * <ul>
+     * <li>The bit initially has the value {@code true}, and the corresponding bit in the argument has the value
+     * {@code false}.
+     * <li>The bit initially has the value {@code false}, and the corresponding bit in the argument has the value
+     * {@code true}.
+     * </ul>
+     *
+     * @param set a bit set
+     * @return this.
+     */
+    public FluentBitSet xor(final BitSet set) {
+        bitSet.xor(set);
+        return this;
+    }
+
+    /**
+     * Performs a logical <b>XOR</b> of this bit set with the bit set argument. This bit set is modified so that a bit in it
+     * has the value {@code true} if and only if one of the following statements holds:
+     * <ul>
+     * <li>The bit initially has the value {@code true}, and the corresponding bit in the argument has the value
+     * {@code false}.
+     * <li>The bit initially has the value {@code false}, and the corresponding bit in the argument has the value
+     * {@code true}.
+     * </ul>
+     *
+     * @param set a bit set
+     * @return this.
+     */
+    public FluentBitSet xor(final FluentBitSet set) {
+        bitSet.xor(set.bitSet);
+        return this;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/lang3/util/package-info.java b/src/main/java/org/apache/commons/lang3/util/package-info.java
new file mode 100644
index 0000000..cd773b0
--- /dev/null
+++ b/src/main/java/org/apache/commons/lang3/util/package-info.java
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ */
+/**
+ * Provides classes that work with the Java {@link java.util} package.
+ *
+ * @since 3.13.0
+ */
+package org.apache.commons.lang3.util;
diff --git a/src/test/java/org/apache/commons/lang3/util/FluentBitSetTest.java b/src/test/java/org/apache/commons/lang3/util/FluentBitSetTest.java
new file mode 100644
index 0000000..83de454
--- /dev/null
+++ b/src/test/java/org/apache/commons/lang3/util/FluentBitSetTest.java
@@ -0,0 +1,1827 @@
+/*
+ * 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.commons.lang3.util;
+
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+
+import java.util.BitSet;
+
+import org.apache.commons.lang3.ArrayUtils;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Tests {@link FluentBitSet}.
+ * <p>
+ * Test code originally from Apache Harmony for FluentBitSet and adapted.
+ * </p>
+ */
+public class FluentBitSetTest {
+
+    private BitSet eightBs;
+    private FluentBitSet eightFbs;
+
+    /**
+     * BeforeEach.
+     */
+    @BeforeEach
+    public void beforeEach() {
+
+        eightFbs = newInstance();
+
+        for (int i = 0; i < 8; i++) {
+            eightFbs.set(i);
+        }
+        eightBs = eightFbs.bitSet();
+    }
+
+    private FluentBitSet newInstance() {
+        return new FluentBitSet();
+    }
+
+    private FluentBitSet newInstance(final int nbits) {
+        return new FluentBitSet(nbits);
+    }
+
+    /**
+     * Tests {@link FluentBitSet#and(FluentBitSet)}.
+     */
+    @Test
+    public void test_and() {
+        // Test for method void java.util.BitSet.and(BitSet)
+        final FluentBitSet bs = newInstance(128);
+        // Initialize the bottom half of the BitSet
+
+        for (int i = 64; i < 128; i++) {
+            bs.set(i);
+        }
+        eightFbs.and(bs);
+        assertFalse(eightFbs.equals(bs), "AND failed to clear bits");
+        eightFbs.set(3);
+        bs.set(3);
+        eightFbs.and(bs);
+        assertTrue(bs.get(3), "AND failed to maintain set bits");
+        bs.and(eightFbs);
+        for (int i = 64; i < 128; i++) {
+            assertFalse(bs.get(i), "Failed to clear extra bits in the receiver BitSet");
+        }
+    }
+
+    /**
+     * Tests {@link FluentBitSet#and(BitSet)}.
+     */
+    @Test
+    public void test_and_BitSet() {
+        // Test for method void java.util.BitSet.and(BitSet)
+        final FluentBitSet bs = newInstance(128);
+        // Initialize the bottom half of the BitSet
+
+        for (int i = 64; i < 128; i++) {
+            bs.set(i);
+        }
+        eightFbs.and(bs.bitSet());
+        assertFalse(eightFbs.equals(bs), "AND failed to clear bits");
+        eightFbs.set(3);
+        bs.set(3);
+        eightFbs.and(bs.bitSet());
+        assertTrue(bs.get(3), "AND failed to maintain set bits");
+        bs.and(eightBs);
+        for (int i = 64; i < 128; i++) {
+            assertFalse(bs.get(i), "Failed to clear extra bits in the receiver BitSet");
+        }
+    }
+
+    /**
+     * Tests {@link FluentBitSet#andNot(BitSet)}.
+     */
+    @Test
+    public void test_andNot() {
+        FluentBitSet bs = (FluentBitSet) eightFbs.clone();
+        bs.clear(5);
+        final FluentBitSet bs2 = newInstance();
+        bs2.set(2);
+        bs2.set(3);
+        bs.andNot(bs2);
+        assertEquals("{0, 1, 4, 6, 7}", bs.toString(), "Incorrect bitset after andNot");
+
+        bs = newInstance(0);
+        bs.andNot(bs2);
+        assertEquals(0, bs.size(), "Incorrect size");
+    }
+
+    /**
+     * Tests {@link FluentBitSet#andNot(BitSet)}.
+     */
+    @Test
+    public void test_andNot_BitSet() {
+        FluentBitSet bs = (FluentBitSet) eightFbs.clone();
+        bs.clear(5);
+        final FluentBitSet bs2 = newInstance();
+        bs2.set(2);
+        bs2.set(3);
+        bs.andNot(bs2.bitSet());
+        assertEquals("{0, 1, 4, 6, 7}", bs.toString(), "Incorrect bitset after andNot");
+
+        bs = newInstance(0);
+        bs.andNot(bs2.bitSet());
+        assertEquals(0, bs.size(), "Incorrect size");
+    }
+
+    /**
+     * Tests {@link FluentBitSet#cardinality()}.
+     */
+    @Test
+    public void test_cardinality() {
+        // test for method int java.util.BitSet.cardinality()
+        final FluentBitSet bs = newInstance(500);
+        bs.set(5);
+        bs.set(32);
+        bs.set(63);
+        bs.set(64);
+        bs.set(71, 110);
+        bs.set(127, 130);
+        bs.set(193);
+        bs.set(450);
+        assertEquals(48, bs.cardinality(), "cardinality() returned wrong value");
+
+        bs.flip(0, 500);
+        assertEquals(452, bs.cardinality(), "cardinality() returned wrong value");
+
+        bs.clear();
+        assertEquals(0, bs.cardinality(), "cardinality() returned wrong value");
+
+        bs.set(0, 500);
+        assertEquals(500, bs.cardinality(), "cardinality() returned wrong value");
+    }
+
+    /**
+     * Tests {@link FluentBitSet#clear()}.
+     */
+    @Test
+    public void test_clear() {
+        eightFbs.clear();
+        for (int i = 0; i < 8; i++) {
+            assertFalse(eightFbs.get(i), "Clear didn't clear bit " + i);
+        }
+        assertEquals(0, eightFbs.length(), "Test1: Wrong length");
+
+        final FluentBitSet bs = newInstance(3400);
+        bs.set(0, bs.size() - 1); // ensure all bits are 1's
+        bs.set(bs.size() - 1);
+        bs.clear();
+        assertEquals(0, bs.length(), "Test2: Wrong length");
+        assertTrue(bs.isEmpty(), "Test2: isEmpty() returned incorrect value");
+        assertEquals(0, bs.cardinality(), "Test2: cardinality() returned incorrect value");
+    }
+
+    /**
+     * Tests {@link FluentBitSet#clear(int)}.
+     */
+    @Test
+    public void test_clearI() {
+        // Test for method void java.util.BitSet.clear(int)
+
+        eightFbs.clear(7);
+        assertFalse(eightFbs.get(7), "Failed to clear bit");
+
+        // Check to see all other bits are still set
+        for (int i = 0; i < 7; i++) {
+            assertTrue(eightFbs.get(i), "Clear cleared incorrect bits");
+        }
+
+        eightFbs.clear(165);
+        assertFalse(eightFbs.get(165), "Failed to clear bit");
+        // Try out of range
+        assertThrows(IndexOutOfBoundsException.class, () -> eightFbs.clear(-1));
+
+        final FluentBitSet bs = newInstance(0);
+        assertEquals(0, bs.length(), "Test1: Wrong length,");
+        assertEquals(0, bs.size(), "Test1: Wrong size,");
+
+        bs.clear(0);
+        assertEquals(0, bs.length(), "Test2: Wrong length,");
+        assertEquals(0, bs.size(), "Test2: Wrong size,");
+
+        bs.clear(60);
+        assertEquals(0, bs.length(), "Test3: Wrong length,");
+        assertEquals(0, bs.size(), "Test3: Wrong size,");
+
+        bs.clear(120);
+        assertEquals(0, bs.size(), "Test4: Wrong size,");
+        assertEquals(0, bs.length(), "Test4: Wrong length,");
+
+        bs.set(25);
+        assertEquals(64, bs.size(), "Test5: Wrong size,");
+        assertEquals(26, bs.length(), "Test5: Wrong length,");
+
+        bs.clear(80);
+        assertEquals(64, bs.size(), "Test6: Wrong size,");
+        assertEquals(26, bs.length(), "Test6: Wrong length,");
+
+        bs.clear(25);
+        assertEquals(64, bs.size(), "Test7: Wrong size,");
+        assertEquals(0, bs.length(), "Test7: Wrong length,");
+    }
+
+    /**
+     * Tests {@link FluentBitSet#clear(int, int)}.
+     */
+    @Test
+    public void test_clearII() {
+        // Regression for HARMONY-98
+        final FluentBitSet bitset = newInstance();
+        for (int i = 0; i < 20; i++) {
+            bitset.set(i);
+        }
+        bitset.clear(10, 10);
+
+        // Test for method void java.util.BitSet.clear(int, int)
+        // pos1 and pos2 are in the same bitset element
+        FluentBitSet bs = newInstance(16);
+        int initialSize = bs.size();
+        bs.set(0, initialSize);
+        bs.clear(5);
+        bs.clear(15);
+        bs.clear(7, 11);
+        for (int i = 0; i < 7; i++) {
+            if (i == 5) {
+                assertFalse(bs.get(i), "Shouldn't have flipped bit " + i);
+            } else {
+                assertTrue(bs.get(i), "Shouldn't have cleared bit " + i);
+            }
+        }
+        for (int i = 7; i < 11; i++) {
+            assertFalse(bs.get(i), "Failed to clear bit " + i);
+        }
+
+        for (int i = 11; i < initialSize; i++) {
+            if (i == 15) {
+                assertFalse(bs.get(i), "Shouldn't have flipped bit " + i);
+            } else {
+                assertTrue(bs.get(i), "Shouldn't have cleared bit " + i);
+            }
+        }
+
+        for (int i = initialSize; i < bs.size(); i++) {
+            assertFalse(bs.get(i), "Shouldn't have flipped bit " + i);
+        }
+
+        // pos1 and pos2 is in the same bitset element, boundry testing
+        bs = newInstance(16);
+        initialSize = bs.size();
+        bs.set(0, initialSize);
+        bs.clear(7, 64);
+        assertEquals(64, bs.size(), "Failed to grow BitSet");
+        for (int i = 0; i < 7; i++) {
+            assertTrue(bs.get(i), "Shouldn't have cleared bit " + i);
+        }
+        for (int i = 7; i < 64; i++) {
+            assertFalse(bs.get(i), "Failed to clear bit " + i);
+        }
+        for (int i = 64; i < bs.size(); i++) {
+            assertTrue(!bs.get(i), "Shouldn't have flipped bit " + i);
+        }
+        // more boundary testing
+        bs = newInstance(32);
+        initialSize = bs.size();
+        bs.set(0, initialSize);
+        bs.clear(0, 64);
+        for (int i = 0; i < 64; i++) {
+            assertFalse(bs.get(i), "Failed to clear bit " + i);
+        }
+        for (int i = 64; i < bs.size(); i++) {
+            assertFalse(bs.get(i), "Shouldn't have flipped bit " + i);
+        }
+
+        bs = newInstance(32);
+        initialSize = bs.size();
+        bs.set(0, initialSize);
+        bs.clear(0, 65);
+        for (int i = 0; i < 65; i++) {
+            assertFalse(bs.get(i), "Failed to clear bit " + i);
+        }
+        for (int i = 65; i < bs.size(); i++) {
+            assertFalse(bs.get(i), "Shouldn't have flipped bit " + i);
+        }
+
+        // pos1 and pos2 are in two sequential bitset elements
+        bs = newInstance(128);
+        initialSize = bs.size();
+        bs.set(0, initialSize);
+        bs.clear(7);
+        bs.clear(110);
+        bs.clear(9, 74);
+        for (int i = 0; i < 9; i++) {
+            if (i == 7) {
+                assertFalse(bs.get(i), "Shouldn't have flipped bit " + i);
+            } else {
+                assertTrue(bs.get(i), "Shouldn't have cleared bit " + i);
+            }
+        }
+        for (int i = 9; i < 74; i++) {
+            assertFalse(bs.get(i), "Failed to clear bit " + i);
+        }
+        for (int i = 74; i < initialSize; i++) {
+            if (i == 110) {
+                assertFalse(bs.get(i), "Shouldn't have flipped bit " + i);
+            } else {
+                assertTrue(bs.get(i), "Shouldn't have cleared bit " + i);
+            }
+        }
+        for (int i = initialSize; i < bs.size(); i++) {
+            assertFalse(bs.get(i), "Shouldn't have flipped bit " + i);
+        }
+
+        // pos1 and pos2 are in two non-sequential bitset elements
+        bs = newInstance(256);
+        bs.set(0, 256);
+        bs.clear(7);
+        bs.clear(255);
+        bs.clear(9, 219);
+        for (int i = 0; i < 9; i++) {
+            if (i == 7) {
+                assertFalse(bs.get(i), "Shouldn't have flipped bit " + i);
+            } else {
+                assertTrue(bs.get(i), "Shouldn't have cleared bit " + i);
+            }
+        }
+
+        for (int i = 9; i < 219; i++) {
+            assertFalse(bs.get(i), "failed to clear bit " + i);
+        }
+
+        for (int i = 219; i < 255; i++) {
+            assertTrue(bs.get(i), "Shouldn't have cleared bit " + i);
+        }
+
+        for (int i = 255; i < bs.size(); i++) {
+            assertFalse(bs.get(i), "Shouldn't have flipped bit " + i);
+        }
+
+        // test illegal args
+        bs = newInstance(10);
+        assertThrows(IndexOutOfBoundsException.class, () -> newInstance(10).clear(-1, 3),
+            "Test1: Attempt to flip with negative index failed to generate exception");
+
+        assertThrows(IndexOutOfBoundsException.class, () -> newInstance(10).clear(2, -1),
+            "Test2: Attempt to flip with negative index failed to generate exception");
+
+        bs.set(2, 4);
+        bs.clear(2, 2);
+        assertTrue(bs.get(2), "Bit got cleared incorrectly ");
+
+        assertThrows(IndexOutOfBoundsException.class, () -> newInstance(10).clear(4, 2),
+            "Test4: Attempt to flip with illegal args failed to generate exception");
+
+        bs = newInstance(0);
+        assertEquals(0, bs.length(), "Test1: Wrong length,");
+        assertEquals(0, bs.size(), "Test1: Wrong size,");
+
+        bs.clear(0, 2);
+        assertEquals(0, bs.length(), "Test2: Wrong length,");
+        assertEquals(0, bs.size(), "Test2: Wrong size,");
+
+        bs.clear(60, 64);
+        assertEquals(0, bs.length(), "Test3: Wrong length,");
+        assertEquals(0, bs.size(), "Test3: Wrong size,");
+
+        bs.clear(64, 120);
+        assertEquals(0, bs.length(), "Test4: Wrong length,");
+        assertEquals(0, bs.size(), "Test4: Wrong size,");
+
+        bs.set(25);
+        assertEquals(26, bs.length(), "Test5: Wrong length,");
+        assertEquals(64, bs.size(), "Test5: Wrong size,");
+
+        bs.clear(60, 64);
+        assertEquals(26, bs.length(), "Test6: Wrong length,");
+        assertEquals(64, bs.size(), "Test6: Wrong size,");
+
+        bs.clear(64, 120);
+        assertEquals(64, bs.size(), "Test7: Wrong size,");
+        assertEquals(26, bs.length(), "Test7: Wrong length,");
+
+        bs.clear(80);
+        assertEquals(64, bs.size(), "Test8: Wrong size,");
+        assertEquals(26, bs.length(), "Test8: Wrong length,");
+
+        bs.clear(25);
+        assertEquals(64, bs.size(), "Test9: Wrong size,");
+        assertEquals(0, bs.length(), "Test9: Wrong length,");
+    }
+
+    /**
+     * Tests {@link FluentBitSet#clear(int...)}.
+     */
+    @Test
+    public void test_clearIntArray() {
+        // Test for method void java.util.BitSet.clear(int)
+
+        eightFbs.clear(new int[] {7});
+        assertFalse(eightFbs.get(7), "Failed to clear bit");
+
+        // Check to see all other bits are still set
+        for (int i = 0; i < 7; i++) {
+            assertTrue(eightFbs.get(i), "Clear cleared incorrect bits");
+        }
+
+        eightFbs.clear(165);
+        assertFalse(eightFbs.get(165), "Failed to clear bit");
+        // Try out of range
+        assertThrows(IndexOutOfBoundsException.class, () -> eightFbs.clear(-1));
+
+        final FluentBitSet bs = newInstance(0);
+        assertEquals(0, bs.length(), "Test1: Wrong length,");
+        assertEquals(0, bs.size(), "Test1: Wrong size,");
+
+        bs.clear(new int[] {0});
+        assertEquals(0, bs.length(), "Test2: Wrong length,");
+        assertEquals(0, bs.size(), "Test2: Wrong size,");
+
+        bs.clear(new int[] {60});
+        assertEquals(0, bs.length(), "Test3: Wrong length,");
+        assertEquals(0, bs.size(), "Test3: Wrong size,");
+
+        bs.clear(new int[] {120});
+        assertEquals(0, bs.size(), "Test4: Wrong size,");
+        assertEquals(0, bs.length(), "Test4: Wrong length,");
+
+        bs.set(25);
+        assertEquals(64, bs.size(), "Test5: Wrong size,");
+        assertEquals(26, bs.length(), "Test5: Wrong length,");
+
+        bs.clear(new int[] {80});
+        assertEquals(64, bs.size(), "Test6: Wrong size,");
+        assertEquals(26, bs.length(), "Test6: Wrong length,");
+
+        bs.clear(new int[] {25});
+        assertEquals(64, bs.size(), "Test7: Wrong size,");
+        assertEquals(0, bs.length(), "Test7: Wrong length,");
+    }
+
+    /**
+     * Tests FluentBitSet#clone()
+     */
+    @Test
+    public void test_clone() {
+        final FluentBitSet bs = (FluentBitSet) eightFbs.clone();
+        assertEquals(bs, eightFbs, "clone failed to return equal BitSet");
+    }
+
+    /**
+     * Tests {@link FluentBitSet#FluentBitSet()}.
+     */
+    @Test
+    public void test_Constructor() {
+        final FluentBitSet bs = newInstance();
+        assertEquals(64, bs.size(), "Create FluentBitSet of incorrect size");
+        assertEquals("{}", bs.toString(), "New FluentBitSet had invalid string representation");
+    }
+
+    /**
+     * Tests {@link FluentBitSet#FluentBitSet(int)}.
+     */
+    @Test
+    public void test_ConstructorInt() {
+        FluentBitSet bs = newInstance(128);
+        assertEquals(128, bs.size(), "Create FluentBitSet of incorrect size");
+        assertEquals("{}", bs.toString(), "New FluentBitSet had invalid string representation: " + bs.toString());
+        // All BitSets are created with elements of multiples of 64
+        bs = newInstance(89);
+        assertEquals(128, bs.size(), "Failed to round FluentBitSet element size");
+
+        assertThrows(NegativeArraySizeException.class, () -> newInstance(-9));
+    }
+
+    /**
+     * Tests {@link FluentBitSet#equals(java.lang.Object)}.
+     */
+    @Test
+    public void test_equals() {
+        FluentBitSet bs;
+        bs = (FluentBitSet) eightFbs.clone();
+        assertEquals(eightFbs, eightFbs, "Same FluentBitSet returned false");
+        assertEquals(bs, eightFbs, "Identical FluentBitSet returned false");
+        bs.clear(6);
+        assertFalse(eightFbs.equals(bs), "Different BitSets returned true");
+        assertFalse(eightFbs.equals(null), "Different BitSets returned true");
+        assertFalse(eightFbs.equals(new Object()), "Different BitSets returned true");
+
+        bs = (FluentBitSet) eightFbs.clone();
+        bs.set(128);
+        assertFalse(eightFbs.equals(bs), "Different sized FluentBitSet with higher bit set returned true");
+        bs.clear(128);
+        assertTrue(eightFbs.equals(bs), "Different sized FluentBitSet with higher bits not set returned false");
+    }
+
+    /**
+     * Tests {@link FluentBitSet#flip(int)}.
+     */
+    @Test
+    public void test_flipI() {
+        // Test for method void java.util.BitSet.flip(int)
+        FluentBitSet bs = newInstance();
+        bs.clear(8);
+        bs.clear(9);
+        bs.set(10);
+        bs.flip(9);
+        assertFalse(bs.get(8), "Failed to flip bit");
+        assertTrue(bs.get(9), "Failed to flip bit");
+        assertTrue(bs.get(10), "Failed to flip bit");
+
+        bs.set(8);
+        bs.set(9);
+        bs.clear(10);
+        bs.flip(9);
+        assertTrue(bs.get(8), "Failed to flip bit");
+        assertFalse(bs.get(9), "Failed to flip bit");
+        assertFalse(bs.get(10), "Failed to flip bit");
+
+        assertThrows(IndexOutOfBoundsException.class, () -> newInstance().flip(-1), "Attempt to flip at negative index failed to generate exception");
+
+        // Try setting a bit on a 64 boundary
+        bs.flip(128);
+        assertEquals(192, bs.size(), "Failed to grow BitSet");
+        assertTrue(bs.get(128), "Failed to flip bit");
+
+        bs = newInstance(64);
+        for (int i = bs.size(); --i >= 0;) {
+            bs.flip(i);
+            assertTrue(bs.get(i), "Test1: Incorrectly flipped bit" + i);
+            assertEquals(i + 1, bs.length(), "Incorrect length");
+            for (int j = bs.size(); --j > i;) {
+                assertTrue(!bs.get(j), "Test2: Incorrectly flipped bit" + j);
+            }
+            for (int j = i; --j >= 0;) {
+                assertTrue(!bs.get(j), "Test3: Incorrectly flipped bit" + j);
+            }
+            bs.flip(i);
+        }
+
+        final FluentBitSet bs0 = newInstance(0);
+        assertEquals(0, bs0.size(), "Test1: Wrong size");
+        assertEquals(0, bs0.length(), "Test1: Wrong length");
+
+        bs0.flip(0);
+        assertEquals(bs0.size(), 64, "Test2: Wrong size");
+        assertEquals(1, bs0.length(), "Test2: Wrong length");
+
+        bs0.flip(63);
+        assertEquals(64, bs0.size(), "Test3: Wrong size");
+        assertEquals(64, bs0.length(), "Test3: Wrong length");
+
+        eightFbs.flip(7);
+        assertTrue(!eightFbs.get(7), "Failed to flip bit 7");
+
+        // Check to see all other bits are still set
+        for (int i = 0; i < 7; i++) {
+            assertTrue(eightFbs.get(i), "Flip flipped incorrect bits");
+        }
+
+        eightFbs.flip(127);
+        assertTrue(eightFbs.get(127), "Failed to flip bit 127");
+
+        eightFbs.flip(127);
+        assertTrue(!eightFbs.get(127), "Failed to flip bit 127");
+    }
+
+    /**
+     * Tests {@link FluentBitSet#clear(int, int)}.
+     */
+    @Test
+    public void test_flipII() {
+        final FluentBitSet bitset = newInstance();
+        for (int i = 0; i < 20; i++) {
+            bitset.set(i);
+        }
+        bitset.flip(10, 10);
+
+        // Test for method void java.util.BitSet.flip(int, int)
+        // pos1 and pos2 are in the same bitset element
+        FluentBitSet bs = newInstance(16);
+        bs.set(7);
+        bs.set(10);
+        bs.flip(7, 11);
+        for (int i = 0; i < 7; i++) {
+            assertTrue(!bs.get(i), "Shouldn't have flipped bit " + i);
+        }
+        assertFalse(bs.get(7), "Failed to flip bit 7");
+        assertTrue(bs.get(8), "Failed to flip bit 8");
+        assertTrue(bs.get(9), "Failed to flip bit 9");
+        assertFalse(bs.get(10), "Failed to flip bit 10");
+        for (int i = 11; i < bs.size(); i++) {
+            assertTrue(!bs.get(i), "Shouldn't have flipped bit " + i);
+        }
+
+        // pos1 and pos2 is in the same bitset element, boundry testing
+        bs = newInstance(16);
+        bs.set(7);
+        bs.set(10);
+        bs.flip(7, 64);
+        assertEquals(64, bs.size(), "Failed to grow BitSet");
+        for (int i = 0; i < 7; i++) {
+            assertTrue(!bs.get(i), "Shouldn't have flipped bit " + i);
+        }
+        assertFalse(bs.get(7), "Failed to flip bit 7");
+        assertTrue(bs.get(8), "Failed to flip bit 8");
+        assertTrue(bs.get(9), "Failed to flip bit 9");
+        assertFalse(bs.get(10), "Failed to flip bit 10");
+        for (int i = 11; i < 64; i++) {
+            assertTrue(bs.get(i), "failed to flip bit " + i);
+        }
+        assertFalse(bs.get(64), "Shouldn't have flipped bit 64");
+
+        // more boundary testing
+        bs = newInstance(32);
+        bs.flip(0, 64);
+        for (int i = 0; i < 64; i++) {
+            assertTrue(bs.get(i), "Failed to flip bit " + i);
+        }
+        assertFalse(bs.get(64), "Shouldn't have flipped bit 64");
+
+        bs = newInstance(32);
+        bs.flip(0, 65);
+        for (int i = 0; i < 65; i++) {
+            assertTrue(bs.get(i), "Failed to flip bit " + i);
+        }
+        assertFalse(bs.get(65), "Shouldn't have flipped bit 65");
+
+        // pos1 and pos2 are in two sequential bitset elements
+        bs = newInstance(128);
+        bs.set(7);
+        bs.set(10);
+        bs.set(72);
+        bs.set(110);
+        bs.flip(9, 74);
+        for (int i = 0; i < 7; i++) {
+            assertFalse(bs.get(i), "Shouldn't have flipped bit " + i);
+        }
+        assertTrue(bs.get(7), "Shouldn't have flipped bit 7");
+        assertFalse(bs.get(8), "Shouldn't have flipped bit 8");
+        assertTrue(bs.get(9), "Failed to flip bit 9");
+        assertFalse(bs.get(10), "Failed to flip bit 10");
+        for (int i = 11; i < 72; i++) {
+            assertTrue(bs.get(i), "failed to flip bit " + i);
+        }
+        assertFalse(bs.get(72), "Failed to flip bit 72");
+        assertTrue(bs.get(73), "Failed to flip bit 73");
+        for (int i = 74; i < 110; i++) {
+            assertFalse(bs.get(i), "Shouldn't have flipped bit " + i);
+        }
+        assertTrue(bs.get(110), "Shouldn't have flipped bit 110");
+        for (int i = 111; i < bs.size(); i++) {
+            assertFalse(bs.get(i), "Shouldn't have flipped bit " + i);
+        }
+
+        // pos1 and pos2 are in two non-sequential bitset elements
+        bs = newInstance(256);
+        bs.set(7);
+        bs.set(10);
+        bs.set(72);
+        bs.set(110);
+        bs.set(181);
+        bs.set(220);
+        bs.flip(9, 219);
+        for (int i = 0; i < 7; i++) {
+            assertFalse(bs.get(i), "Shouldn't have flipped bit " + i);
+        }
+        assertTrue(bs.get(7), "Shouldn't have flipped bit 7");
+        assertFalse(bs.get(8), "Shouldn't have flipped bit 8");
+        assertTrue(bs.get(9), "Failed to flip bit 9");
+        assertFalse(bs.get(10), "Failed to flip bit 10");
+        for (int i = 11; i < 72; i++) {
+            assertTrue(bs.get(i), "failed to flip bit " + i);
+        }
+        assertFalse(bs.get(72), "Failed to flip bit 72");
+        for (int i = 73; i < 110; i++) {
+            assertTrue(bs.get(i), "failed to flip bit " + i);
+        }
+        assertFalse(bs.get(110), "Failed to flip bit 110");
+        for (int i = 111; i < 181; i++) {
+            assertTrue(bs.get(i), "failed to flip bit " + i);
+        }
+        assertFalse(bs.get(181), "Failed to flip bit 181");
+        for (int i = 182; i < 219; i++) {
+            assertTrue(bs.get(i), "failed to flip bit " + i);
+        }
+        assertFalse(bs.get(219), "Shouldn't have flipped bit 219");
+        assertTrue(bs.get(220), "Shouldn't have flipped bit 220");
+        for (int i = 221; i < bs.size(); i++) {
+            assertTrue(!bs.get(i), "Shouldn't have flipped bit " + i);
+        }
+
+        // test illegal args
+        bs = newInstance(10);
+        try {
+            bs.flip(-1, 3);
+            fail("Test1: Attempt to flip with  negative index failed to generate exception");
+        } catch (final IndexOutOfBoundsException e) {
+            // correct behavior
+        }
+
+        try {
+            bs.flip(2, -1);
+            fail("Test2: Attempt to flip with negative index failed to generate exception");
+        } catch (final IndexOutOfBoundsException e) {
+            // correct behavior
+        }
+
+        try {
+            bs.flip(4, 2);
+            fail("Test4: Attempt to flip with illegal args failed to generate exception");
+        } catch (final IndexOutOfBoundsException e) {
+            // correct behavior
+        }
+    }
+
+    /**
+     * Tests {@link FluentBitSet#get(int)}.
+     */
+    @Test
+    public void test_getI() {
+        // Test for method boolean java.util.BitSet.get(int)
+
+        FluentBitSet bs = newInstance();
+        bs.set(8);
+        assertFalse(eightFbs.get(99), "Get returned true for index out of range");
+        assertTrue(eightFbs.get(3), "Get returned false for set value");
+        assertFalse(bs.get(0), "Get returned true for a non set value");
+
+        assertThrows(IndexOutOfBoundsException.class, () -> newInstance().get(-1), "Attempt to get at negative index failed to generate exception");
+
+        bs = newInstance(1);
+        assertFalse(bs.get(64), "Access greater than size");
+
+        bs = newInstance();
+        bs.set(63);
+        assertTrue(bs.get(63), "Test highest bit");
+
+        bs = newInstance(0);
+        assertEquals(0, bs.length(), "Test1: Wrong length,");
+        assertEquals(0, bs.size(), "Test1: Wrong size,");
+
+        bs.get(2);
+        assertEquals(0, bs.length(), "Test2: Wrong length,");
+        assertEquals(0, bs.size(), "Test2: Wrong size,");
+
+        bs.get(70);
+        assertEquals(0, bs.length(), "Test3: Wrong length,");
+        assertEquals(0, bs.size(), "Test3: Wrong size,");
+
+    }
+
+    /**
+     * Tests {@link FluentBitSet#get(int, int)}.
+     */
+    @Test
+    public void test_getII() {
+        final FluentBitSet bitset = newInstance(30);
+        bitset.get(3, 3);
+
+        // Test for method boolean java.util.BitSet.get(int, int)
+        FluentBitSet bs, resultbs, correctbs;
+        bs = newInstance(512);
+        bs.set(3, 9);
+        bs.set(10, 20);
+        bs.set(60, 75);
+        bs.set(121);
+        bs.set(130, 140);
+
+        // pos1 and pos2 are in the same bitset element, at index0
+        resultbs = bs.get(3, 6);
+        correctbs = newInstance(3);
+        correctbs.set(0, 3);
+        assertEquals(correctbs, resultbs, "Test1: Returned incorrect BitSet");
+
+        // pos1 and pos2 are in the same bitset element, at index 1
+        resultbs = bs.get(100, 125);
+        correctbs = newInstance(25);
+        correctbs.set(21);
+        assertEquals(correctbs, resultbs, "Test2: Returned incorrect BitSet");
+
+        // pos1 in bitset element at index 0, and pos2 in bitset element at
+        // index 1
+        resultbs = bs.get(15, 125);
+        correctbs = newInstance(25);
+        correctbs.set(0, 5);
+        correctbs.set(45, 60);
+        correctbs.set(121 - 15);
+        assertEquals(correctbs, resultbs, "Test3: Returned incorrect BitSet");
+
+        // pos1 in bitset element at index 1, and pos2 in bitset element at
+        // index 2
+        resultbs = bs.get(70, 145);
+        correctbs = newInstance(75);
+        correctbs.set(0, 5);
+        correctbs.set(51);
+        correctbs.set(60, 70);
+        assertEquals(correctbs, resultbs, "Test4: Returned incorrect BitSet");
+
+        // pos1 in bitset element at index 0, and pos2 in bitset element at
+        // index 2
+        resultbs = bs.get(5, 145);
+        correctbs = newInstance(140);
+        correctbs.set(0, 4);
+        correctbs.set(5, 15);
+        correctbs.set(55, 70);
+        correctbs.set(116);
+        correctbs.set(125, 135);
+        assertEquals(correctbs, resultbs, "Test5: Returned incorrect BitSet");
+
+        // pos1 in bitset element at index 0, and pos2 in bitset element at
+        // index 3
+        resultbs = bs.get(5, 250);
+        correctbs = newInstance(200);
+        correctbs.set(0, 4);
+        correctbs.set(5, 15);
+        correctbs.set(55, 70);
+        correctbs.set(116);
+        correctbs.set(125, 135);
+        assertEquals(correctbs, resultbs, "Test6: Returned incorrect BitSet");
+
+        assertEquals(bs.get(0, bs.size()), bs, "equality principle 1 ");
+
+        // more tests
+        FluentBitSet bs2 = newInstance(129);
+        bs2.set(0, 20);
+        bs2.set(62, 65);
+        bs2.set(121, 123);
+        resultbs = bs2.get(1, 124);
+        correctbs = newInstance(129);
+        correctbs.set(0, 19);
+        correctbs.set(61, 64);
+        correctbs.set(120, 122);
+        assertEquals(correctbs, resultbs, "Test7: Returned incorrect BitSet");
+
+        // equality principle with some boundary conditions
+        bs2 = newInstance(128);
+        bs2.set(2, 20);
+        bs2.set(62);
+        bs2.set(121, 123);
+        bs2.set(127);
+        resultbs = bs2.get(0, bs2.size());
+        assertEquals(resultbs, bs2, "equality principle 2 ");
+
+        bs2 = newInstance(128);
+        bs2.set(2, 20);
+        bs2.set(62);
+        bs2.set(121, 123);
+        bs2.set(127);
+        bs2.flip(0, 128);
+        resultbs = bs2.get(0, bs.size());
+        assertEquals(resultbs, bs2, "equality principle 3 ");
+
+        bs = newInstance(0);
+        assertEquals(0, bs.length(), "Test1: Wrong length,");
+        assertEquals(0, bs.size(), "Test1: Wrong size,");
+
+        bs.get(0, 2);
+        assertEquals(0, bs.length(), "Test2: Wrong length,");
+        assertEquals(0, bs.size(), "Test2: Wrong size,");
+
+        bs.get(60, 64);
+        assertEquals(0, bs.length(), "Test3: Wrong length,");
+        assertEquals(0, bs.size(), "Test3: Wrong size,");
+
+        bs.get(64, 120);
+        assertEquals(0, bs.length(), "Test4: Wrong length,");
+        assertEquals(0, bs.size(), "Test4: Wrong size,");
+
+        bs.set(25);
+        assertEquals(26, bs.length(), "Test5: Wrong length,");
+        assertEquals(64, bs.size(), "Test5: Wrong size,");
+
+        bs.get(60, 64);
+        assertEquals(26, bs.length(), "Test6: Wrong length,");
+        assertEquals(64, bs.size(), "Test6: Wrong size,");
+
+        bs.get(64, 120);
+        assertEquals(64, bs.size(), "Test7: Wrong size,");
+        assertEquals(26, bs.length(), "Test7: Wrong length,");
+
+        bs.get(80);
+        assertEquals(64, bs.size(), "Test8: Wrong size,");
+        assertEquals(26, bs.length(), "Test8: Wrong length,");
+
+        bs.get(25);
+        assertEquals(64, bs.size(), "Test9: Wrong size,");
+        assertEquals(26, bs.length(), "Test9: Wrong length,");
+
+    }
+
+    /**
+     * Tests {@link FluentBitSet#hashCode()}.
+     */
+    @Test
+    public void test_hashCode() {
+        // Test for method int java.util.BitSet.hashCode()
+        final FluentBitSet bs = (FluentBitSet) eightFbs.clone();
+        bs.clear(2);
+        bs.clear(6);
+        assertEquals(bs.bitSet().hashCode(), bs.hashCode(), "BitSet returns wrong hash value");
+        bs.set(10);
+        bs.clear(3);
+        assertEquals(97, bs.hashCode(), "BitSet returns wrong hash value");
+    }
+
+    /**
+     * Tests {@link FluentBitSet#intersects(FluentBitSet)}.
+     */
+    @Test
+    public void test_intersects() {
+        // Test for method boolean java.util.BitSet.intersects(BitSet)
+        final FluentBitSet bs = newInstance(500);
+        bs.set(5);
+        bs.set(63);
+        bs.set(64);
+        bs.set(71, 110);
+        bs.set(127, 130);
+        bs.set(192);
+        bs.set(450);
+
+        final FluentBitSet bs2 = newInstance(8);
+        assertFalse(bs.intersects(bs2), "Test1: intersects() returned incorrect value");
+        assertFalse(bs2.intersects(bs), "Test1: intersects() returned incorrect value");
+
+        bs2.set(4);
+        assertFalse(bs.intersects(bs2), "Test2: intersects() returned incorrect value");
+        assertFalse(bs2.intersects(bs), "Test2: intersects() returned incorrect value");
+
+        bs2.clear();
+        bs2.set(5);
+        assertTrue(bs.intersects(bs2), "Test3: intersects() returned incorrect value");
+        assertTrue(bs2.intersects(bs), "Test3: intersects() returned incorrect value");
+
+        bs2.clear();
+        bs2.set(63);
+        assertTrue(bs.intersects(bs2), "Test4: intersects() returned incorrect value");
+        assertTrue(bs2.intersects(bs), "Test4: intersects() returned incorrect value");
+
+        bs2.clear();
+        bs2.set(80);
+        assertTrue(bs.intersects(bs2), "Test5: intersects() returned incorrect value");
+        assertTrue(bs2.intersects(bs), "Test5: intersects() returned incorrect value");
+
+        bs2.clear();
+        bs2.set(127);
+        assertTrue(bs.intersects(bs2), "Test6: intersects() returned incorrect value");
+        assertTrue(bs2.intersects(bs), "Test6: intersects() returned incorrect value");
+
+        bs2.clear();
+        bs2.set(192);
+        assertTrue(bs.intersects(bs2), "Test7: intersects() returned incorrect value");
+        assertTrue(bs2.intersects(bs), "Test7: intersects() returned incorrect value");
+
+        bs2.clear();
+        bs2.set(450);
+        assertTrue(bs.intersects(bs2), "Test8: intersects() returned incorrect value");
+        assertTrue(bs2.intersects(bs), "Test8: intersects() returned incorrect value");
+
+        bs2.clear();
+        bs2.set(500);
+        assertFalse(bs.intersects(bs2), "Test9: intersects() returned incorrect value");
+        assertFalse(bs2.intersects(bs), "Test9: intersects() returned incorrect value");
+    }
+
+    /**
+     * Tests {@link FluentBitSet#intersects(BitSet)}.
+     */
+    @Test
+    public void test_intersects_BitSet() {
+        // Test for method boolean java.util.BitSet.intersects(BitSet)
+        final FluentBitSet bs = newInstance(500);
+        bs.set(5);
+        bs.set(63);
+        bs.set(64);
+        bs.set(71, 110);
+        bs.set(127, 130);
+        bs.set(192);
+        bs.set(450);
+
+        final FluentBitSet bs2 = newInstance(8);
+        assertFalse(bs.intersects(bs2.bitSet()), "Test1: intersects() returned incorrect value");
+        assertFalse(bs2.intersects(bs.bitSet()), "Test1: intersects() returned incorrect value");
+
+        bs2.set(4);
+        assertFalse(bs.intersects(bs2.bitSet()), "Test2: intersects() returned incorrect value");
+        assertFalse(bs2.intersects(bs.bitSet()), "Test2: intersects() returned incorrect value");
+
+        bs2.clear();
+        bs2.set(5);
+        assertTrue(bs.intersects(bs2.bitSet()), "Test3: intersects() returned incorrect value");
+        assertTrue(bs2.intersects(bs.bitSet()), "Test3: intersects() returned incorrect value");
+
+        bs2.clear();
+        bs2.set(63);
+        assertTrue(bs.intersects(bs2.bitSet()), "Test4: intersects() returned incorrect value");
+        assertTrue(bs2.intersects(bs.bitSet()), "Test4: intersects() returned incorrect value");
+
+        bs2.clear();
+        bs2.set(80);
+        assertTrue(bs.intersects(bs2.bitSet()), "Test5: intersects() returned incorrect value");
+        assertTrue(bs2.intersects(bs.bitSet()), "Test5: intersects() returned incorrect value");
+
+        bs2.clear();
+        bs2.set(127);
+        assertTrue(bs.intersects(bs2.bitSet()), "Test6: intersects() returned incorrect value");
+        assertTrue(bs2.intersects(bs.bitSet()), "Test6: intersects() returned incorrect value");
+
+        bs2.clear();
+        bs2.set(192);
+        assertTrue(bs.intersects(bs2.bitSet()), "Test7: intersects() returned incorrect value");
+        assertTrue(bs2.intersects(bs.bitSet()), "Test7: intersects() returned incorrect value");
+
+        bs2.clear();
+        bs2.set(450);
+        assertTrue(bs.intersects(bs2.bitSet()), "Test8: intersects() returned incorrect value");
+        assertTrue(bs2.intersects(bs.bitSet()), "Test8: intersects() returned incorrect value");
+
+        bs2.clear();
+        bs2.set(500);
+        assertFalse(bs.intersects(bs2.bitSet()), "Test9: intersects() returned incorrect value");
+        assertFalse(bs2.intersects(bs.bitSet()), "Test9: intersects() returned incorrect value");
+    }
+
+    /**
+     * Tests {@link FluentBitSet#isEmpty()}.
+     */
+    @Test
+    public void test_isEmpty() {
+        final FluentBitSet bs = newInstance(500);
+        assertTrue(bs.isEmpty(), "Test: isEmpty() returned wrong value");
+
+        // at bitset element 0
+        bs.set(3);
+        assertFalse(bs.isEmpty(), "Test0: isEmpty() returned wrong value");
+
+        // at bitset element 1
+        bs.clear();
+        bs.set(12);
+        assertFalse(bs.isEmpty(), "Test1: isEmpty() returned wrong value");
+
+        // at bitset element 2
+        bs.clear();
+        bs.set(128);
+        assertFalse(bs.isEmpty(), "Test2: isEmpty() returned wrong value");
+
+        // boundary testing
+        bs.clear();
+        bs.set(459);
+        assertFalse(bs.isEmpty(), "Test3: isEmpty() returned wrong value");
+
+        bs.clear();
+        bs.set(511);
+        assertFalse(bs.isEmpty(), "Test4: isEmpty() returned wrong value");
+    }
+
+    /**
+     * Tests {@link FluentBitSet#length()}.
+     */
+    @Test
+    public void test_length() {
+        final FluentBitSet bs = newInstance();
+        assertEquals(0, bs.length(), "BitSet returned wrong length");
+        bs.set(5);
+        assertEquals(6, bs.length(), "BitSet returned wrong length");
+        bs.set(10);
+        assertEquals(11, bs.length(), "BitSet returned wrong length");
+        bs.set(432);
+        assertEquals(433, bs.length(), "BitSet returned wrong length");
+        bs.set(300);
+        assertEquals(433, bs.length(), "BitSet returned wrong length");
+    }
+
+    /**
+     * Tests {@link FluentBitSet#nextClearBit(int)}.
+     */
+    @Test
+    public void test_nextClearBitI() {
+        // Test for method int java.util.BitSet.nextSetBit()
+        final FluentBitSet bs = newInstance(500);
+        bs.set(0, bs.size() - 1); // ensure all the bits from 0 to bs.size()
+                                  // -1
+        bs.set(bs.size() - 1); // are set to true
+        bs.clear(5);
+        bs.clear(32);
+        bs.clear(63);
+        bs.clear(64);
+        bs.clear(71, 110);
+        bs.clear(127, 130);
+        bs.clear(193);
+        bs.clear(450);
+        try {
+            bs.nextClearBit(-1);
+            fail("Expected IndexOutOfBoundsException for negative index");
+        } catch (final IndexOutOfBoundsException e) {
+            // correct behavior
+        }
+        assertEquals(5, bs.nextClearBit(0), "nextClearBit() returned the wrong value");
+        assertEquals(5, bs.nextClearBit(5), "nextClearBit() returned the wrong value");
+        assertEquals(32, bs.nextClearBit(6), "nextClearBit() returned the wrong value");
+        assertEquals(32, bs.nextClearBit(32), "nextClearBit() returned the wrong value");
+        assertEquals(63, bs.nextClearBit(33), "nextClearBit() returned the wrong value");
+
+        // boundary tests
+        assertEquals(63, bs.nextClearBit(63), "nextClearBit() returned the wrong value");
+        assertEquals(64, bs.nextClearBit(64), "nextClearBit() returned the wrong value");
+
+        // at bitset element 1
+        assertEquals(71, bs.nextClearBit(65), "nextClearBit() returned the wrong value");
+        assertEquals(71, bs.nextClearBit(71), "nextClearBit() returned the wrong value");
+        assertEquals(72, bs.nextClearBit(72), "nextClearBit() returned the wrong value");
+        assertEquals(127, bs.nextClearBit(110), "nextClearBit() returned the wrong value");
+
+        // boundary tests
+        assertEquals(127, bs.nextClearBit(127), "nextClearBit() returned the wrong value");
+        assertEquals(128, bs.nextClearBit(128), "nextClearBit() returned the wrong value");
+
+        // at bitset element 2
+        assertEquals(193, bs.nextClearBit(130), "nextClearBit() returned the wrong value");
+        assertEquals(193, bs.nextClearBit(191), "nextClearBit() returned the wrong value");
+
+        assertEquals(193, bs.nextClearBit(192), "nextClearBit() returned the wrong value");
+        assertEquals(193, bs.nextClearBit(193), "nextClearBit() returned the wrong value");
+        assertEquals(450, bs.nextClearBit(194), "nextClearBit() returned the wrong value");
+        assertEquals(450, bs.nextClearBit(255), "nextClearBit() returned the wrong value");
+        assertEquals(450, bs.nextClearBit(256), "nextClearBit() returned the wrong value");
+        assertEquals(450, bs.nextClearBit(450), "nextClearBit() returned the wrong value");
+
+        // bitset has 1 still the end of bs.size() -1, but calling nextClearBit
+        // with any index value
+        // after the last true bit should return bs.size(),
+        assertEquals(512, bs.nextClearBit(451), "nextClearBit() returned the wrong value");
+        assertEquals(512, bs.nextClearBit(511), "nextClearBit() returned the wrong value");
+        assertEquals(512, bs.nextClearBit(512), "nextClearBit() returned the wrong value");
+
+        // if the index is larger than bs.size(), nextClearBit should return
+        // index;
+        assertEquals(513, bs.nextClearBit(513), "nextClearBit() returned the wrong value");
+        assertEquals(800, bs.nextClearBit(800), "nextClearBit() returned the wrong value");
+    }
+
+    /**
+     * Tests {@link FluentBitSet#nextSetBit(int)}.
+     */
+    @Test
+    public void test_nextSetBitI() {
+        // Test for method int java.util.BitSet.nextSetBit()
+        final FluentBitSet bs = newInstance(500);
+        bs.set(5);
+        bs.set(32);
+        bs.set(63);
+        bs.set(64);
+        bs.set(71, 110);
+        bs.set(127, 130);
+        bs.set(193);
+        bs.set(450);
+        try {
+            bs.nextSetBit(-1);
+            fail("Expected IndexOutOfBoundsException for negative index");
+        } catch (final IndexOutOfBoundsException e) {
+            // correct behavior
+        }
+        assertEquals(5, bs.nextSetBit(0), "nextSetBit() returned the wrong value");
+        assertEquals(5, bs.nextSetBit(5), "nextSetBit() returned the wrong value");
+        assertEquals(32, bs.nextSetBit(6), "nextSetBit() returned the wrong value");
+        assertEquals(32, bs.nextSetBit(32), "nextSetBit() returned the wrong value");
+        assertEquals(63, bs.nextSetBit(33), "nextSetBit() returned the wrong value");
+
+        // boundary tests
+        assertEquals(63, bs.nextSetBit(63), "nextSetBit() returned the wrong value");
+        assertEquals(64, bs.nextSetBit(64), "nextSetBit() returned the wrong value");
+
+        // at bitset element 1
+        assertEquals(71, bs.nextSetBit(65), "nextSetBit() returned the wrong value");
+        assertEquals(71, bs.nextSetBit(71), "nextSetBit() returned the wrong value");
+        assertEquals(72, bs.nextSetBit(72), "nextSetBit() returned the wrong value");
+        assertEquals(127, bs.nextSetBit(110), "nextSetBit() returned the wrong value");
+
+        // boundary tests
+        assertEquals(127, bs.nextSetBit(127), "nextSetBit() returned the wrong value");
+        assertEquals(128, bs.nextSetBit(128), "nextSetBit() returned the wrong value");
+
+        // at bitset element 2
+        assertEquals(193, bs.nextSetBit(130), "nextSetBit() returned the wrong value");
+
+        assertEquals(193, bs.nextSetBit(191), "nextSetBit() returned the wrong value");
+        assertEquals(193, bs.nextSetBit(192), "nextSetBit() returned the wrong value");
+        assertEquals(193, bs.nextSetBit(193), "nextSetBit() returned the wrong value");
+        assertEquals(450, bs.nextSetBit(194), "nextSetBit() returned the wrong value");
+        assertEquals(450, bs.nextSetBit(255), "nextSetBit() returned the wrong value");
+        assertEquals(450, bs.nextSetBit(256), "nextSetBit() returned the wrong value");
+        assertEquals(450, bs.nextSetBit(450), "nextSetBit() returned the wrong value");
+
+        assertEquals(-1, bs.nextSetBit(451), "nextSetBit() returned the wrong value");
+        assertEquals(-1, bs.nextSetBit(511), "nextSetBit() returned the wrong value");
+        assertEquals(-1, bs.nextSetBit(512), "nextSetBit() returned the wrong value");
+        assertEquals(-1, bs.nextSetBit(800), "nextSetBit() returned the wrong value");
+    }
+
+    /**
+     * Tests {@link FluentBitSet#or(FluentBitSet)}.
+     */
+    @Test
+    public void test_or() {
+        // Test for method void java.util.BitSet.or(BitSet)
+        FluentBitSet bs = newInstance(128);
+        bs.or(eightFbs);
+        for (int i = 0; i < 8; i++) {
+            assertTrue(bs.get(i), "OR failed to set bits");
+        }
+
+        bs = newInstance(0);
+        bs.or(eightFbs);
+        for (int i = 0; i < 8; i++) {
+            assertTrue(bs.get(i), "OR(0) failed to set bits");
+        }
+
+        eightFbs.clear(5);
+        bs = newInstance(128);
+        bs.or(eightFbs);
+        assertFalse(bs.get(5), "OR set a bit which should be off");
+    }
+
+    /**
+     * Tests {@link FluentBitSet#or(BitSet)}.
+     */
+    @Test
+    public void test_or_BitSet() {
+        // Test for method void java.util.BitSet.or(BitSet)
+        FluentBitSet bs = newInstance(128);
+        bs.or(eightFbs.bitSet());
+        for (int i = 0; i < 8; i++) {
+            assertTrue(bs.get(i), "OR failed to set bits");
+        }
+
+        bs = newInstance(0);
+        bs.or(eightFbs.bitSet());
+        for (int i = 0; i < 8; i++) {
+            assertTrue(bs.get(i), "OR(0) failed to set bits");
+        }
+
+        eightFbs.clear(5);
+        bs = newInstance(128);
+        bs.or(eightFbs.bitSet());
+        assertFalse(bs.get(5), "OR set a bit which should be off");
+    }
+
+    /**
+     * Tests {@link FluentBitSet#or(FluentBitSet)}.
+     */
+    @Test
+    public void test_or_FluentBitSetArray() {
+        // Test for method void java.util.BitSet.or(BitSet)
+        FluentBitSet bs = newInstance(128);
+        bs.or(new FluentBitSet[] {eightFbs});
+        for (int i = 0; i < 8; i++) {
+            assertTrue(bs.get(i), "OR failed to set bits");
+        }
+
+        bs = newInstance(0);
+        bs.or(new FluentBitSet[] {eightFbs});
+        for (int i = 0; i < 8; i++) {
+            assertTrue(bs.get(i), "OR(0) failed to set bits");
+        }
+
+        eightFbs.clear(5);
+        bs = newInstance(128);
+        bs.or(new FluentBitSet[] {eightFbs});
+        assertFalse(bs.get(5), "OR set a bit which should be off");
+    }
+
+    /**
+     * Tests {@link FluentBitSet#previousClearBit(int)}.
+     */
+    @Test
+    public void test_previousClearBit() {
+        final FluentBitSet bs = newInstance();
+        assertEquals(1, bs.previousClearBit(1), "previousClearBit");
+    }
+
+    /**
+     * Tests {@link FluentBitSet#previousSetBit(int)}.
+     */
+    @Test
+    public void test_previousSetBit() {
+        final FluentBitSet bs = newInstance();
+        assertEquals(-1, bs.previousSetBit(1), "previousSetBit");
+    }
+
+    /**
+     * Tests {@link FluentBitSet#set(int, int)}.
+     */
+    @Test
+    public void test_setII() {
+        final FluentBitSet bitset = newInstance(30);
+        bitset.set(29, 29);
+
+        // Test for method void java.util.BitSet.set(int, int)
+        // pos1 and pos2 are in the same bitset element
+        FluentBitSet bs = newInstance(16);
+        bs.set(5);
+        bs.set(15);
+        bs.set(7, 11);
+        for (int i = 0; i < 7; i++) {
+            if (i == 5) {
+                assertTrue(bs.get(i), "Shouldn't have flipped bit " + i);
+            } else {
+                assertFalse(bs.get(i), "Shouldn't have set bit " + i);
+            }
+        }
+        for (int i = 7; i < 11; i++) {
+            assertTrue(bs.get(i), "Failed to set bit " + i);
+        }
+        for (int i = 11; i < bs.size(); i++) {
+            if (i == 15) {
+                assertTrue(bs.get(i), "Shouldn't have flipped bit " + i);
+            } else {
+                assertFalse(bs.get(i), "Shouldn't have set bit " + i);
+            }
+        }
+
+        // pos1 and pos2 is in the same bitset element, boundry testing
+        bs = newInstance(16);
+        bs.set(7, 64);
+        assertEquals(64, bs.size(), "Failed to grow BitSet");
+        for (int i = 0; i < 7; i++) {
+            assertFalse(bs.get(i), "Shouldn't have set bit " + i);
+        }
+        for (int i = 7; i < 64; i++) {
+            assertTrue(bs.get(i), "Failed to set bit " + i);
+        }
+        assertFalse(bs.get(64), "Shouldn't have set bit 64");
+
+        // more boundary testing
+        bs = newInstance(32);
+        bs.set(0, 64);
+        for (int i = 0; i < 64; i++) {
+            assertTrue(bs.get(i), "Failed to set bit " + i);
+        }
+        assertFalse(bs.get(64), "Shouldn't have set bit 64");
+
+        bs = newInstance(32);
+        bs.set(0, 65);
+        for (int i = 0; i < 65; i++) {
+            assertTrue(bs.get(i), "Failed to set bit " + i);
+        }
+        assertFalse(bs.get(65), "Shouldn't have set bit 65");
+
+        // pos1 and pos2 are in two sequential bitset elements
+        bs = newInstance(128);
+        bs.set(7);
+        bs.set(110);
+        bs.set(9, 74);
+        for (int i = 0; i < 9; i++) {
+            if (i == 7) {
+                assertTrue(bs.get(i), "Shouldn't have flipped bit " + i);
+            } else {
+                assertFalse(bs.get(i), "Shouldn't have set bit " + i);
+            }
+        }
+        for (int i = 9; i < 74; i++) {
+            assertTrue(bs.get(i), "Failed to set bit " + i);
+        }
+        for (int i = 74; i < bs.size(); i++) {
+            if (i == 110) {
+                assertTrue(bs.get(i), "Shouldn't have flipped bit " + i);
+            } else {
+                assertFalse(bs.get(i), "Shouldn't have set bit " + i);
+            }
+        }
+
+        // pos1 and pos2 are in two non-sequential bitset elements
+        bs = newInstance(256);
+        bs.set(7);
+        bs.set(255);
+        bs.set(9, 219);
+        for (int i = 0; i < 9; i++) {
+            if (i == 7) {
+                assertTrue(bs.get(i), "Shouldn't have set flipped " + i);
+            } else {
+                assertFalse(bs.get(i), "Shouldn't have set bit " + i);
+            }
+        }
+
+        for (int i = 9; i < 219; i++) {
+            assertTrue(bs.get(i), "failed to set bit " + i);
+        }
+
+        for (int i = 219; i < 255; i++) {
+            assertFalse(bs.get(i), "Shouldn't have set bit " + i);
+        }
+
+        assertTrue(bs.get(255), "Shouldn't have flipped bit 255");
+
+        // test illegal args
+        bs = newInstance(10);
+        try {
+            bs.set(-1, 3);
+            fail("Test1: Attempt to flip with  negative index failed to generate exception");
+        } catch (final IndexOutOfBoundsException e) {
+            // Correct behavior
+        }
+
+        try {
+            bs.set(2, -1);
+            fail("Test2: Attempt to flip with negative index failed to generate exception");
+        } catch (final IndexOutOfBoundsException e) {
+            // Correct behavior
+        }
+
+        bs.set(2, 2);
+        assertFalse(bs.get(2), "Bit got set incorrectly ");
+
+        try {
+            bs.set(4, 2);
+            fail("Test4: Attempt to flip with illegal args failed to generate exception");
+        } catch (final IndexOutOfBoundsException e) {
+            // Correct behavior
+        }
+    }
+
+    /**
+     * Tests {@link FluentBitSet#set(int, int, boolean)}.
+     */
+    @Test
+    public void test_setIIZ() {
+        // Test for method void java.util.BitSet.set(int, int, boolean)
+        eightFbs.set(3, 6, false);
+        assertTrue(!eightFbs.get(3) && !eightFbs.get(4) && !eightFbs.get(5), "Should have set bits 3, 4, and 5 to false");
+
+        eightFbs.set(3, 6, true);
+        assertTrue(eightFbs.get(3) && eightFbs.get(4) && eightFbs.get(5), "Should have set bits 3, 4, and 5 to true");
+
+    }
+
+    /**
+     * Tests {@link FluentBitSet#setInclusive(int, int)}.
+     */
+    @Test
+    public void test_setInclusive() {
+        final FluentBitSet bitset = newInstance(30);
+        bitset.set(29, 29);
+
+        // Test for method void java.util.BitSet.set(int, int)
+        // pos1 and pos2 are in the same bitset element
+        FluentBitSet bs = newInstance(16);
+        bs.set(5);
+        bs.set(15);
+        bs.setInclusive(7, 11);
+        for (int i = 0; i < 7; i++) {
+            if (i == 5) {
+                assertTrue(bs.get(i), "Shouldn't have flipped bit " + i);
+            } else {
+                assertFalse(bs.get(i), "Shouldn't have set bit " + i);
+            }
+        }
+        for (int i = 7; i < 12; i++) {
+            assertTrue(bs.get(i), "Failed to set bit " + i);
+        }
+        for (int i = 12; i < bs.size(); i++) {
+            if (i == 15) {
+                assertTrue(bs.get(i), "Shouldn't have flipped bit " + i);
+            } else {
+                assertFalse(bs.get(i), "Shouldn't have set bit " + i);
+            }
+        }
+
+        // pos1 and pos2 is in the same bitset element, boundry testing
+        bs = newInstance(16);
+        bs.setInclusive(7, 64);
+        assertEquals(128, bs.size(), "Failed to grow BitSet");
+        for (int i = 0; i < 7; i++) {
+            assertFalse(bs.get(i), "Shouldn't have set bit " + i);
+        }
+        for (int i = 7; i < 65; i++) {
+            assertTrue(bs.get(i), "Failed to set bit " + i);
+        }
+        assertFalse(bs.get(65), "Shouldn't have set bit 64");
+
+        // more boundary testing
+        bs = newInstance(32);
+        bs.setInclusive(0, 64);
+        for (int i = 0; i < 65; i++) {
+            assertTrue(bs.get(i), "Failed to set bit " + i);
+        }
+        assertFalse(bs.get(65), "Shouldn't have set bit 64");
+
+        bs = newInstance(32);
+        bs.setInclusive(0, 65);
+        for (int i = 0; i < 66; i++) {
+            assertTrue(bs.get(i), "Failed to set bit " + i);
+        }
+        assertFalse(bs.get(66), "Shouldn't have set bit 65");
+
+        // pos1 and pos2 are in two sequential bitset elements
+        bs = newInstance(128);
+        bs.set(7);
+        bs.set(110);
+        bs.setInclusive(9, 74);
+        for (int i = 0; i < 9; i++) {
+            if (i == 7) {
+                assertTrue(bs.get(i), "Shouldn't have flipped bit " + i);
+            } else {
+                assertFalse(bs.get(i), "Shouldn't have set bit " + i);
+            }
+        }
+        for (int i = 9; i < 75; i++) {
+            assertTrue(bs.get(i), "Failed to set bit " + i);
+        }
+        for (int i = 75; i < bs.size(); i++) {
+            if (i == 110) {
+                assertTrue(bs.get(i), "Shouldn't have flipped bit " + i);
+            } else {
+                assertFalse(bs.get(i), "Shouldn't have set bit " + i);
+            }
+        }
+
+        // pos1 and pos2 are in two non-sequential bitset elements
+        bs = newInstance(256);
+        bs.set(7);
+        bs.set(255);
+        bs.setInclusive(9, 219);
+        for (int i = 0; i < 9; i++) {
+            if (i == 7) {
+                assertTrue(bs.get(i), "Shouldn't have set flipped " + i);
+            } else {
+                assertFalse(bs.get(i), "Shouldn't have set bit " + i);
+            }
+        }
+
+        for (int i = 9; i < 220; i++) {
+            assertTrue(bs.get(i), "failed to set bit " + i);
+        }
+
+        for (int i = 220; i < 255; i++) {
+            assertFalse(bs.get(i), "Shouldn't have set bit " + i);
+        }
+
+        assertTrue(bs.get(255), "Shouldn't have flipped bit 255");
+
+        // test illegal args
+        bs = newInstance(10);
+        try {
+            bs.setInclusive(-1, 3);
+            fail("Test1: Attempt to flip with  negative index failed to generate exception");
+        } catch (final IndexOutOfBoundsException e) {
+            // Correct behavior
+        }
+
+        try {
+            bs.setInclusive(2, -1);
+            fail("Test2: Attempt to flip with negative index failed to generate exception");
+        } catch (final IndexOutOfBoundsException e) {
+            // Correct behavior
+        }
+
+        bs.setInclusive(2, 2);
+        assertFalse(bs.get(3), "Bit got set incorrectly ");
+
+        try {
+            bs.setInclusive(4, 2);
+            fail("Test4: Attempt to flip with illegal args failed to generate exception");
+        } catch (final IndexOutOfBoundsException e) {
+            // Correct behavior
+        }
+    }
+
+    /**
+     * Tests {@link FluentBitSet#set(int)}.
+     */
+    @Test
+    public void test_setInt() {
+        // Test for method void java.util.BitSet.set(int)
+
+        FluentBitSet bs = newInstance();
+        bs.set(8);
+        assertTrue(bs.get(8), "Failed to set bit");
+
+        try {
+            bs.set(-1);
+            fail("Attempt to set at negative index failed to generate exception");
+        } catch (final IndexOutOfBoundsException e) {
+            // Correct behavior
+        }
+
+        // Try setting a bit on a 64 boundary
+        bs.set(128);
+        assertEquals(192, bs.size(), "Failed to grow BitSet");
+        assertTrue(bs.get(128), "Failed to set bit");
+
+        bs = newInstance(64);
+        for (int i = bs.size(); --i >= 0;) {
+            bs.set(i);
+            assertTrue(bs.get(i), "Incorrectly set");
+            assertEquals(i + 1, bs.length(), "Incorrect length");
+            for (int j = bs.size(); --j > i;) {
+                assertFalse(bs.get(j), "Incorrectly set bit " + j);
+            }
+            for (int j = i; --j >= 0;) {
+                assertFalse(bs.get(j), "Incorrectly set bit " + j);
+            }
+            bs.clear(i);
+        }
+
+        bs = newInstance(0);
+        assertEquals(0, bs.length(), "Test1: Wrong length");
+        bs.set(0);
+        assertEquals(1, bs.length(), "Test2: Wrong length");
+    }
+
+    /**
+     * Tests {@link FluentBitSet#set(int...)}.
+     */
+    @Test
+    public void test_setIntArray() {
+        // Test for method void java.util.BitSet.set(int)
+
+        FluentBitSet bs = newInstance();
+        bs.set(new int[] {8});
+        assertTrue(bs.get(8), "Failed to set bit");
+
+        try {
+            bs.set(new int[] {-1});
+            fail("Attempt to set at negative index failed to generate exception");
+        } catch (final IndexOutOfBoundsException e) {
+            // Correct behavior
+        }
+
+        // Try setting a bit on a 64 boundary
+        bs.set(new int[] {128});
+        assertEquals(192, bs.size(), "Failed to grow BitSet");
+        assertTrue(bs.get(128), "Failed to set bit");
+
+        bs = newInstance(64);
+        for (int i = bs.size(); --i >= 0;) {
+            bs.set(new int[] {i});
+            assertTrue(bs.get(i), "Incorrectly set");
+            assertEquals(i + 1, bs.length(), "Incorrect length");
+            for (int j = bs.size(); --j > i;) {
+                assertFalse(bs.get(j), "Incorrectly set bit " + j);
+            }
+            for (int j = i; --j >= 0;) {
+                assertFalse(bs.get(j), "Incorrectly set bit " + j);
+            }
+            bs.clear(i);
+        }
+
+        bs = newInstance(0);
+        assertEquals(0, bs.length(), "Test1: Wrong length");
+        bs.set(new int[] {0});
+        assertEquals(1, bs.length(), "Test2: Wrong length");
+    }
+
+    /**
+     * Tests {@link FluentBitSet#set(int, boolean)}.
+     */
+    @Test
+    public void test_setIZ() {
+        // Test for method void java.util.BitSet.set(int, boolean)
+        eightFbs.set(5, false);
+        assertFalse(eightFbs.get(5), "Should have set bit 5 to true");
+
+        eightFbs.set(5, true);
+        assertTrue(eightFbs.get(5), "Should have set bit 5 to false");
+    }
+
+    /**
+     * Tests {@link FluentBitSet#setInclusive(int, int)}.
+     */
+    @Test
+    public void test_setRangeInclusive() {
+        // Test for method int java.util.BitSet.size()
+        assertEquals(64, eightFbs.size(), "Returned incorrect size");
+        eightFbs.set(129);
+        assertTrue(eightFbs.size() >= 129, "Returned incorrect size");
+
+    }
+
+    /**
+     * Tests {@link FluentBitSet#size()}.
+     */
+    @Test
+    public void test_size() {
+        // Test for method int java.util.BitSet.size()
+        assertEquals(64, eightFbs.size(), "Returned incorrect size");
+        eightFbs.set(129);
+        assertTrue(eightFbs.size() >= 129, "Returned incorrect size");
+
+    }
+
+    /**
+     * Tests {@link FluentBitSet#previousSetBit(int)}.
+     */
+    @Test
+    public void test_stream() {
+        final FluentBitSet bs = newInstance();
+        assertEquals(0, bs.stream().count(), "stream");
+    }
+
+    /**
+     * Tests {@link FluentBitSet#previousSetBit(int)}.
+     */
+    @Test
+    public void test_toByteArray() {
+        final FluentBitSet bs = newInstance();
+        assertArrayEquals(ArrayUtils.EMPTY_BYTE_ARRAY, bs.toByteArray(), "stream");
+    }
+
+    /**
+     * Tests {@link FluentBitSet#previousSetBit(int)}.
+     */
+    @Test
+    public void test_toLongArray() {
+        final FluentBitSet bs = newInstance();
+        assertArrayEquals(ArrayUtils.EMPTY_LONG_ARRAY, bs.toLongArray(), "stream");
+    }
+
+    /**
+     * Tests {@link FluentBitSet#toString()}.
+     */
+    @Test
+    public void test_toString() {
+        // Test for method java.lang.String java.util.BitSet.toString()
+        assertEquals("{0, 1, 2, 3, 4, 5, 6, 7}", eightFbs.toString(), "Returned incorrect string representation");
+        eightFbs.clear(2);
+        assertEquals("{0, 1, 3, 4, 5, 6, 7}", eightFbs.toString(), "Returned incorrect string representation");
+    }
+
+    /**
+     * Tests {@link FluentBitSet#xor(FluentBitSet)}.
+     */
+    @Test
+    public void test_xor() {
+        // Test for method void java.util.BitSet.xor(BitSet)
+
+        FluentBitSet bs = (FluentBitSet) eightFbs.clone();
+        bs.xor(eightFbs);
+        for (int i = 0; i < 8; i++) {
+            assertFalse(bs.get(i), "XOR failed to clear bits");
+        }
+
+        bs.xor(eightFbs);
+        for (int i = 0; i < 8; i++) {
+            assertTrue(bs.get(i), "XOR failed to set bits");
+        }
+
+        bs = newInstance(0);
+        bs.xor(eightFbs);
+        for (int i = 0; i < 8; i++) {
+            assertTrue(bs.get(i), "XOR(0) failed to set bits");
+        }
+
+        bs = newInstance();
+        bs.set(63);
+        assertEquals("{63}", bs.toString(), "Test highest bit");
+    }
+
+    /**
+     * Tests {@link FluentBitSet#xor(BitSet)}.
+     */
+    @Test
+    public void test_xor_BitSet() {
+        // Test for method void java.util.BitSet.xor(BitSet)
+
+        FluentBitSet bs = (FluentBitSet) eightFbs.clone();
+        bs.xor(eightFbs.bitSet());
+        for (int i = 0; i < 8; i++) {
+            assertFalse(bs.get(i), "XOR failed to clear bits");
+        }
+
+        bs.xor(eightFbs.bitSet());
+        for (int i = 0; i < 8; i++) {
+            assertTrue(bs.get(i), "XOR failed to set bits");
+        }
+
+        bs = newInstance(0);
+        bs.xor(eightFbs.bitSet());
+        for (int i = 0; i < 8; i++) {
+            assertTrue(bs.get(i), "XOR(0) failed to set bits");
+        }
+
+        bs = newInstance();
+        bs.set(63);
+        assertEquals("{63}", bs.toString(), "Test highest bit");
+    }
+
+}