#vulnerable code 
                              public void merge(final CueballFilePath base,
                    final List<CueballFilePath> deltas,
                    final String newBasePath,
                    final int keyHashSize,
                    final int valueSize,
                    ValueTransformer transformer,
                    int hashIndexBits,
                    CompressionCodec compressionCodec) throws IOException {
    // Array of stream buffers for the base and all deltas in order
    CueballStreamBuffer[] cueballStreamBuffers = new CueballStreamBuffer[deltas.size() + 1];

    // Open the current base
    CueballStreamBuffer cueballBaseStreamBuffer = new CueballStreamBuffer(base.getPath(), 0,
        keyHashSize, valueSize, hashIndexBits, compressionCodec);
    cueballStreamBuffers[0] = cueballBaseStreamBuffer;

    // Open all the deltas
    int i = 1;
    for (CueballFilePath delta : deltas) {
      CueballStreamBuffer cueballStreamBuffer =
          new CueballStreamBuffer(delta.getPath(), i, keyHashSize, valueSize, hashIndexBits, compressionCodec);
      cueballStreamBuffers[i++] = cueballStreamBuffer;
    }

    // Output stream for the new base to be written. intentionally unbuffered, the writer below will do that on its own.
    OutputStream newCueballBaseOutputStream = new FileOutputStream(newBasePath);

    // Note that we intentionally omit the hasher here, since it will *not* be used
    CueballWriter newCueballBaseWriter =
        new CueballWriter(newCueballBaseOutputStream, keyHashSize, null, valueSize, compressionCodec, hashIndexBits);

    while (true) {
      // Find the stream buffer with the next smallest key hash
      CueballStreamBuffer cueballStreamBufferToUse = null;
      for (i = 0; i < cueballStreamBuffers.length; i++) {
        if (cueballStreamBuffers[i].anyRemaining()) {
          if (cueballStreamBufferToUse == null) {
            cueballStreamBufferToUse = cueballStreamBuffers[i];
          } else {
            int comparison = cueballStreamBufferToUse.compareTo(cueballStreamBuffers[i]);
            if (comparison == 0) {
              // If two equal key hashes are found, use the most recent value (i.e. the one from the lastest delta)
              // and skip (consume) the older ones
              cueballStreamBufferToUse.consume();
              cueballStreamBufferToUse = cueballStreamBuffers[i];
            } else if (comparison == 1) {
              // Found a stream buffer with a smaller key hash
              cueballStreamBufferToUse = cueballStreamBuffers[i];
            }
          }
        }
      }

      if (cueballStreamBufferToUse == null) {
        // Nothing more to write
        break;
      }

      // Transform if necessary
      if (transformer != null) {
        transformer.transform(cueballStreamBufferToUse.getBuffer(),
            cueballStreamBufferToUse.getCurrentOffset() + keyHashSize,
            cueballStreamBufferToUse.getIndex());
      }

      // Get next key hash and value
      final ByteBuffer keyHash = ByteBuffer.wrap(cueballStreamBufferToUse.getBuffer(),
          cueballStreamBufferToUse.getCurrentOffset(), keyHashSize);
      final ByteBuffer valueBytes = ByteBuffer.wrap(cueballStreamBufferToUse.getBuffer(),
          cueballStreamBufferToUse.getCurrentOffset() + keyHashSize, valueSize);

      // Write next key hash and value
      newCueballBaseWriter.writeHash(keyHash, valueBytes);
      cueballStreamBufferToUse.consume();
    }

    // Close all buffers and the base writer
    for (CueballStreamBuffer cueballStreamBuffer : cueballStreamBuffers) {
      cueballStreamBuffer.close();
    }
    newCueballBaseWriter.close();
  } 
                            #location 81 
                            #vulnerability type RESOURCE_LEAK
#fixed code
                              public void merge(final CueballFilePath base,
                    final List<CueballFilePath> deltas,
                    final String newBasePath,
                    final int keyHashSize,
                    final int valueSize,
                    ValueTransformer transformer,
                    int hashIndexBits,
                    CompressionCodec compressionCodec) throws IOException {

    CueballStreamBufferMergeSort cueballStreamBufferMergeSort = new CueballStreamBufferMergeSort(base,
        deltas,
        keyHashSize,
        hashIndexBits,
        valueSize,
        compressionCodec,
        transformer);

    // Output stream for the new base to be written. intentionally unbuffered, the writer below will do that on its own.
    OutputStream newCueballBaseOutputStream = new FileOutputStream(newBasePath);

    // Note that we intentionally omit the hasher here, since it will *not* be used
    CueballWriter newCueballBaseWriter =
        new CueballWriter(newCueballBaseOutputStream, keyHashSize, null, valueSize, compressionCodec, hashIndexBits);

    while (true) {
      CueballStreamBufferMergeSort.KeyHashValuePair keyValuePair = cueballStreamBufferMergeSort.nextKeyValuePair();
      if (keyValuePair == null) {
        break;
      }

      // Write next key hash and value
      newCueballBaseWriter.writeHash(keyValuePair.keyHash, keyValuePair.value);
    }

    // Close all buffers and the base writer
    cueballStreamBufferMergeSort.close();
    newCueballBaseWriter.close();
  }