protected void RoundTripIOTestShortPacket(
      byte testType,
      int syncOrAsync,
      int numIrps,
      int endpointmaxPacketSize,
      boolean[] acceptShortPacket,
      boolean[] verifyAcceptShortPacket,
      int[] OUTLength,
      int[] OUTOffset,
      int[] OUTExpectedLength,
      Exception[] OUTexpectedException,
      int[] INLength,
      int[] INOffset,
      int[] INExpectedLength,
      Exception[] INexpectedException,
      byte[] transformType) {

    // Note that this code is based on IOTests.RounTripTest which handles IRP, IRPList, and Byte
    // array.  Since only IRPs
    // are being sent in this test, some of the complexity has been removed; however,  although the
    // numIrps is always
    // one for this test, the code has not been changed to get rid of the arrays.

    // ensure all values set up
    Assert.assertEquals(numIrps, transformType.length);
    Assert.assertEquals(numIrps, OUTLength.length);
    Assert.assertEquals(numIrps, OUTOffset.length);
    Assert.assertEquals(numIrps, acceptShortPacket.length);
    Assert.assertEquals(numIrps, verifyAcceptShortPacket.length);
    Assert.assertEquals(numIrps, OUTExpectedLength.length);
    Assert.assertEquals(numIrps, OUTexpectedException.length);
    Assert.assertEquals(numIrps, INLength.length);
    Assert.assertEquals(numIrps, INOffset.length);
    Assert.assertEquals(numIrps, INExpectedLength.length);
    Assert.assertEquals(numIrps, INexpectedException.length);

    Assert.assertNotNull("usbDevice is null, but should not be null.", usbDevice);
    Assert.assertEquals("For short packet test, number of IRPs should be 1.", 1, numIrps);

    /*
     * set up Pipes and add listeners
     */
    UsbPipe inPipe = null;
    UsbPipe outPipe = null;

    // we need two int values back from method call so we'll put them in the array
    int[] pipeListIndexes = new int[2];
    int inPipeArrayIndex = 0;
    int outPipeArrayIndex = 1;

    IOMethods.findINandOUTPipesForTest(
        usbPipeListGlobal,
        endpointmaxPacketSize,
        pipeListIndexes,
        inPipeArrayIndex,
        outPipeArrayIndex);
    inPipe = (UsbPipe) usbPipeListGlobal.get(pipeListIndexes[inPipeArrayIndex]);
    outPipe = (UsbPipe) usbPipeListGlobal.get(pipeListIndexes[outPipeArrayIndex]);
    IOMethods.verifyThePipes(inPipe, outPipe, endpointmaxPacketSize);

    inPipe.addUsbPipeListener(inPipeListener);
    outPipe.addUsbPipeListener(outPipeListener);

    IOMethods.openPipe(inPipe);
    IOMethods.openPipe(outPipe);

    // define buffers to be used in IRPs or sent as byte[]
    byte[] aggregateOUTbuffer = null;
    byte[] aggregateINbuffer = null;

    // for byte array and single IRP, the OUT and IN buffers are the length specified by the tests
    aggregateOUTbuffer = new byte[OUTLength[0]];
    aggregateINbuffer = new byte[INLength[0]];

    printDebug(
        "RoundTripTestShortPacket -- IRP "
            + transmitListStrings[syncOrAsync]
            + " "
            + endpointTypeStrings[endpointType]);

    /*
     * Create the OUT and IN IRPs or byte arrrays
     */
    List transmitBuffers = new ArrayList();
    List listOfOUTIrps = new ArrayList();
    List listOfINIrps = new ArrayList();

    for (int k = 0; k < numIrps; k++) {
      // create transmit buffer for OUT and IN IRPs
      TransmitBuffer currentTransmitBuffer = new TransmitBuffer(transformType[k], OUTLength[k]);
      transmitBuffers.add(currentTransmitBuffer);

      // create OUT IRP
      UsbIrp currentOUTIrp = outPipe.createUsbIrp();
      listOfOUTIrps.add(currentOUTIrp);

      // set data in OUT IRP
      currentOUTIrp.setData(aggregateOUTbuffer, OUTOffset[k], OUTLength[k]);
      currentOUTIrp.setAcceptShortPacket(acceptShortPacket[k]);

      // OUT IRP is ready to go!

      if (endpointType == UsbConst.ENDPOINT_TYPE_ISOCHRONOUS) {
        /*
         * For isochronous transfers, all IN Irps will have an offset of zero and
         * the same buffer length.
         */
        // get the longest required buffer length for all of the IRPs. All of the IRPs in the list
        // have the same length buffer.
        int standardISOINBufferLength = INLength[0];
        for (int l = 1; l < numIrps; l++) {
          if (INLength[l] > standardISOINBufferLength) {
            standardISOINBufferLength = INLength[l];
          }
        }
        // now that the largest has been found, set the length for each in IRP to the new length
        for (int l = 0; l < numIrps; l++) {
          INLength[l] = standardISOINBufferLength;
        }
        int standardISOINBufferOffset = 0;

        // int numCopies = 1;//there will be numCopies * numIrps in the list of ISO In Irps
        int totalNumCopies = 40; // there will be numCopies * numIrps in the list of ISO In Irps
        for (int indexOfCurrentCopy = 0;
            indexOfCurrentCopy < totalNumCopies;
            indexOfCurrentCopy++) {
          // create IN IRP
          UsbIrp currentINIrp = inPipe.createUsbIrp();
          listOfINIrps.add(currentINIrp);
          byte[] currentINbuffer = new byte[standardISOINBufferLength];

          currentINIrp.setData(
              currentINbuffer, standardISOINBufferOffset, standardISOINBufferLength);
          currentINIrp.setAcceptShortPacket(acceptShortPacket[k]);
        }

      } else {
        // create IN IRP
        UsbIrp currentINIrp = inPipe.createUsbIrp();
        listOfINIrps.add(currentINIrp);
        /*
         * set data in IN IRP -- note that no data is copied to IN byte[] before setting data in IRP.
         * byte[] will be filled by IN operation.
         */
        currentINIrp.setData(aggregateINbuffer, INOffset[k], INLength[k]);
        currentINIrp.setAcceptShortPacket(acceptShortPacket[k]);
      }
    }

    // copy individual transmitbuffers into single OUT  buffer
    for (int k = 0; k < numIrps; k++) {
      TransmitBuffer currentTransmitBuffer = (TransmitBuffer) transmitBuffers.get(k);

      System.arraycopy(
          currentTransmitBuffer.getOutBuffer(), 0, aggregateOUTbuffer, OUTOffset[k], OUTLength[k]);
    }

    // ensure all events are clear before sending IRPs
    inPipeEvents.clear();
    outPipeEvents.clear();

    // send both the OUT and IN IRPs
    sendOUTandIN(testType, transmitList[syncOrAsync], inPipe, outPipe, listOfINIrps, listOfOUTIrps);

    printDebug("return from sendoutandin");
    if (endpointType == UsbConst.ENDPOINT_TYPE_ISOCHRONOUS) {
      clearOutTheINEventAndIrpListForISO(inPipeEvents, listOfINIrps);
    }

    // verify IRP data against expected values
    for (int k = 0; k < numIrps; k++) {
      UsbIrp submittedOUTIRP = (UsbIrp) listOfOUTIrps.get(k);

      // verify OUT IRP after successful transmit
      VerifyIrpMethods.verifyUsbIrpAfterEvent(
          submittedOUTIRP,
          (EventObject) outPipeEvents.get(k),
          ((TransmitBuffer) transmitBuffers.get(k)).getOutBuffer(),
          OUTExpectedLength[k],
          OUTexpectedException[k],
          acceptShortPacket[k],
          verifyAcceptShortPacket[k],
          OUTOffset[k],
          OUTLength[k]);

      UsbIrp submittedINIRP = (UsbIrp) listOfINIrps.get(k);
      byte[] expectedINBuffer = ((TransmitBuffer) transmitBuffers.get(k)).getInBuffer();

      // if exception is expected, do not verify the In buffer
      if (INexpectedException[k] != null) {
        expectedINBuffer = null;

        // if we got a USB exception as expected, then clear the endpoint
        if (submittedINIRP.isUsbException()) {

          try {

            StandardRequest.clearFeature(
                usbDevice,
                UsbConst.REQUESTTYPE_RECIPIENT_ENDPOINT,
                UsbConst.FEATURE_SELECTOR_ENDPOINT_HALT,
                inPipe.getUsbEndpoint().getUsbEndpointDescriptor().bEndpointAddress());

            printDebug("clear feature");
          } catch (Exception e) {
            Assert.fail("Exception clearing halt on enpoint after short packet exception.");
          }
        } else {
          printDebug("not clear feature");
        }
      }

      // verify IN IRP after successful submit
      VerifyIrpMethods.verifyUsbIrpAfterEvent(
          submittedINIRP,
          (EventObject) inPipeEvents.get(k),
          expectedINBuffer,
          INExpectedLength[k],
          INexpectedException[k],
          acceptShortPacket[k],
          verifyAcceptShortPacket[k],
          INOffset[k],
          INLength[k]);
    }

    IOMethods.closePipe(inPipe);
    IOMethods.closePipe(outPipe);

    inPipe.removeUsbPipeListener(inPipeListener);
    outPipe.removeUsbPipeListener(outPipeListener);
  };