docs: @Nonnull
    @ReturnsMutableCopy
    public ICommonsList <IFileItem> parseRequest (@Nonnull final IRequestContext aCtx) throws FileUploadException
    {
      final ICommonsList <IFileItem> aItems = new CommonsArrayList <> ();
      boolean bSuccessful = false;
      try
      {
        final IFileItemIterator aItemIter = getItemIterator (aCtx);
        final IFileItemFactory aFileItemFactory = getFileItemFactory ();
        if (aFileItemFactory == null)
          throw new IllegalStateException ("No FileItemFactory has been set.");
  
        while (aItemIter.hasNext ())
        {
          final IFileItemStream aFileItemStream = aItemIter.next ();
          // Don't use getName() here to prevent an InvalidFileNameException.
          final IFileItem aFileItem = aFileItemFactory.createItem (aFileItemStream.getFieldName (),
                                                                   aFileItemStream.getContentType (),
                                                                   aFileItemStream.isFormField (),
                                                                   aFileItemStream.getNameUnchecked ());
          aItems.add (aFileItem);
          InputStream aIS = null;
          OutputStream aOS = null;
          try
          {
            aIS = aFileItemStream.openStream ();
            aOS = aFileItem.getOutputStream ();
            final byte [] aBuffer = new byte [8192];
            int nBytesRead;
            // potentially blocking read
            while ((nBytesRead = aIS.read (aBuffer, 0, aBuffer.length)) > -1)
            {
              aOS.write (aBuffer, 0, nBytesRead);
            }
          }
          catch (final FileUploadIOException ex)
          {
            throw (FileUploadException) ex.getCause ();
          }
          catch (final IOException ex)
          {
            throw new IOFileUploadException ("Processing of " +
                                             RequestHelper.MULTIPART_FORM_DATA +
                                             " request failed. " +
                                             ex.getMessage (),
                                             ex);
          }
          finally
          {
            StreamHelper.close (aIS);
            StreamHelper.close (aOS);
          }
          if (aFileItem instanceof IFileItemHeadersSupport)
          {
            final IFileItemHeaders aFileItemHeaders = aFileItemStream.getHeaders ();
            ((IFileItemHeadersSupport) aFileItem).setHeaders (aFileItemHeaders);
          }
        }
        bSuccessful = true;
        return aItems;
      }
      catch (final FileUploadIOException ex)
      {
        throw (FileUploadException) ex.getCause ();
      }
      catch (final IOException ex)
      {
        throw new FileUploadException (ex.getMessage (), ex);
      }
      finally
      {
        if (!bSuccessful)
        {
          // Delete all file items
          for (final IFileItem aFileItem : aItems)
          {
            try
            {
              aFileItem.delete ();
            }
            catch (final Exception ex)
            {
              // ignore it
              if (LOGGER.isErrorEnabled ())
                LOGGER.error ("Failed to delete fileItem " + aFileItem, ex);
            }
          }
        }
      }
    }