private byte[] callCipher(
            Cipher cipher, byte[] input, int expectedOutputLength, CallPattern callPattern)
            throws GeneralSecurityException {
        switch (callPattern) {
            case DO_FINAL: {
                return cipher.doFinal(input);
            }
            case DO_FINAL_WITH_OFFSET: {
                byte[] inputCopy = new byte[input.length + 100];
                int inputOffset = 42;
                System.arraycopy(input, 0, inputCopy, inputOffset, input.length);
                return cipher.doFinal(inputCopy, inputOffset, input.length);
            }
            case UPDATE_DO_FINAL: {
                byte[] output1 = cipher.update(input);
                byte[] output2 = cipher.doFinal();
                return concatArrays(output1, output2);
            }
            case MULTIPLE_UPDATE_DO_FINAL: {
                int input1Length = input.length / 2;
                int input2Length = input.length - input1Length;
                byte[] output1 = cipher.update(input, /*inputOffset= */ 0, input1Length);
                int input2Offset = input1Length;
                byte[] output2 = cipher.update(input, input2Offset, input2Length);
                byte[] output3 = cipher.update(new byte[0]);
                byte[] output4 = cipher.doFinal();
                return concatArrays(output1, output2, output3, output4);
            }
            case UPDATE_DO_FINAL_WITH_OUTPUT_ARRAY: {
                byte[] output1 = cipher.update(input);
                int output1Length = (output1 == null) ? 0 : output1.length;
                byte[] output2 = new byte[expectedOutputLength - output1Length];
                int written = cipher.doFinal(output2, /*outputOffset= */ 0);
                assertEquals(expectedOutputLength - output1Length, written);
                return concatArrays(output1, output2);
            }
            case UPDATE_DO_FINAL_WITH_OUTPUT_ARRAY_AND_OFFSET: {
                byte[] output1 = cipher.update(input);
                int output1Length = (output1 == null) ? 0 : output1.length;
                byte[] output2WithOffset = new byte[expectedOutputLength + 100];
                int outputOffset = 42;
                int written = cipher.doFinal(output2WithOffset, outputOffset);
                assertEquals(expectedOutputLength - output1Length, written);
                byte[] output2 = Arrays.copyOfRange(output2WithOffset, outputOffset, outputOffset + written);
                return concatArrays(output1, output2);
            }
            case DO_FINAL_WITH_INPUT_OUTPUT_ARRAY: {
                byte[] output = new byte[expectedOutputLength];
                int written = cipher.doFinal(input, /*inputOffset= */ 0, input.length, output);
                assertEquals(expectedOutputLength, written);
                return output;
            }
            case DO_FINAL_WITH_INPUT_OUTPUT_ARRAY_AND_OFFSET: {
                byte[] inputWithOffset = new byte[input.length + 100];
                int inputOffset = 37;
                System.arraycopy(input, 0, inputWithOffset, inputOffset, input.length);
                byte[] outputWithOffset = new byte[expectedOutputLength + 100];
                int outputOffset = 21;
                int written = cipher.doFinal(
                    inputWithOffset, inputOffset, input.length, outputWithOffset, outputOffset);
                return Arrays.copyOfRange(outputWithOffset, outputOffset, outputOffset + written);
            }
            case UPDATE_DO_FINAL_WITH_INPUT_OUTPUT_ARRAY: {
                int input1Length = input.length / 2;
                byte[] output = new byte[expectedOutputLength];
                int written1 = cipher.update(input, /*inputOffset= */ 0, input1Length, output);
                int input2Offset = input1Length;
                int input2Length = input.length - input1Length;
                int outputOffset = written1;
                int written2 = cipher.doFinal(
                    input, input2Offset, input2Length, output, outputOffset);
                assertEquals(expectedOutputLength, written1 + written2);
                return output;
            }
        }
        throw new IllegalArgumentException("Unsupported CallPattern: " + callPattern);
    }
Calls an initialized cipher with different equivalent call patterns.
common/src/test/java/org/conscrypt/javax/crypto/CipherBasicsTest.java