protected static int extractInt(int[] data, int startBit, int length) {
        if (data == null) {
            throw new IllegalArgumentException("data == null");
        }
        if (startBit < 0) {
            throw new IllegalArgumentException("startBit < 0");
        }
        if (length <= 0) {
            throw new IllegalArgumentException("length <= 0");
        }
        if (length > 31) {
            throw new IllegalArgumentException("length > 31");
        }
        if ((length + startBit) > (data.length * 8)) {
            throw new IllegalArgumentException("(length + startBit) > (data.length * 8)");
        }

        // create an int array where each entry represents a single bit
        int[] bits = new int[data.length * 8];
        for (int i = 0; i < data.length; i++) {
            for (int j = 0; j < 8; j++) {
                bits[(i * 8) + j] = (data[i] >>> (7 - j)) & 1;
            }
        }

        // extractInt the bits needed for the return value
        int[] returnBits = new int[length];
        for (int i = 0; i < returnBits.length; i++) {
            returnBits[i] = bits[startBit + i];
        }

        // convert the return bits into an integer
        // this loop could be combined with the loop in the previous step, but is kept separate for better readability
        int returnInt = 0;
        for (int i = 0; i < returnBits.length; i++) {
            returnInt |= (returnBits[i] << ((returnBits.length - 1) - i));
        }

        return returnInt;
    }