// Path: src/main/java/org/apache/commons/fileupload2/servlet/ServletFileUpload.java
// public class ServletFileUpload extends FileUpload {
// 
//     /**
//      * Constant for HTTP POST method.
//      */
//     private static final String POST_METHOD = "POST";
// 
//     // ---------------------------------------------------------- Class methods
// 
//     /**
//      * Utility method that determines whether the request contains multipart
//      * content.
//      *
//      * @param request The servlet request to be evaluated. Must be non-null.
//      *
//      * @return {@code true} if the request is multipart;
//      *         {@code false} otherwise.
//      */
//     public static final boolean isMultipartContent(
//             final HttpServletRequest request) {
//         if (!POST_METHOD.equalsIgnoreCase(request.getMethod())) {
//             return false;
//         }
//         return FileUploadBase.isMultipartContent(new ServletRequestContext(request));
//     }
// 
//     // ----------------------------------------------------------- Constructors
// 
//     /**
//      * Constructs an uninitialized instance of this class. A factory must be
//      * configured, using {@code setFileItemFactory()}, before attempting
//      * to parse requests.
//      *
//      * @see FileUpload#FileUpload(FileItemFactory)
//      */
//     public ServletFileUpload() {
//     }
// 
//     /**
//      * Constructs an instance of this class which uses the supplied factory to
//      * create {@code FileItem} instances.
//      *
//      * @see FileUpload#FileUpload()
//      * @param fileItemFactory The factory to use for creating file items.
//      */
//     public ServletFileUpload(final FileItemFactory fileItemFactory) {
//         super(fileItemFactory);
//     }
// 
//     // --------------------------------------------------------- Public methods
// 
//     /**
//      * Processes an <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>
//      * compliant {@code multipart/form-data} stream.
//      *
//      * @param request The servlet request to be parsed.
//      *
//      * @return A list of {@code FileItem} instances parsed from the
//      *         request, in the order that they were transmitted.
//      *
//      * @throws FileUploadException if there are problems reading/parsing
//      *                             the request or storing files.
//      */
//     public List<FileItem> parseRequest(final HttpServletRequest request)
//     throws FileUploadException {
//         return parseRequest(new ServletRequestContext(request));
//     }
// 
//     /**
//      * Processes an <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>
//      * compliant {@code multipart/form-data} stream.
//      *
//      * @param request The servlet request to be parsed.
//      *
//      * @return A map of {@code FileItem} instances parsed from the request.
//      *
//      * @throws FileUploadException if there are problems reading/parsing
//      *                             the request or storing files.
//      *
//      * @since 1.3
//      */
//     public Map<String, List<FileItem>> parseParameterMap(final HttpServletRequest request)
//             throws FileUploadException {
//         return parseParameterMap(new ServletRequestContext(request));
//     }
// 
//     /**
//      * Processes an <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>
//      * compliant {@code multipart/form-data} stream.
//      *
//      * @param request The servlet request to be parsed.
//      *
//      * @return An iterator to instances of {@code FileItemStream}
//      *         parsed from the request, in the order that they were
//      *         transmitted.
//      *
//      * @throws FileUploadException if there are problems reading/parsing
//      *                             the request or storing files.
//      * @throws IOException An I/O error occurred. This may be a network
//      *   error while communicating with the client or a problem while
//      *   storing the uploaded content.
//      */
//     public FileItemIterator getItemIterator(final HttpServletRequest request)
//     throws FileUploadException, IOException {
//         return super.getItemIterator(new ServletRequestContext(request));
//     }
// 
// }


import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import org.apache.commons.fileupload2.servlet.ServletFileUpload;
import org.junit.jupiter.api.Test;
     */
    @Test
    public void testProgressListener() throws Exception {
        final int NUM_ITEMS = 512;
        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
        for (int i = 0;  i < NUM_ITEMS;  i++) {
            final String header = "-----1234\r\n"
                + "Content-Disposition: form-data; name=\"field" + (i + 1) + "\"\r\n"
                + "\r\n";
            baos.write(header.getBytes(StandardCharsets.US_ASCII));
            for (int j = 0;  j < 16384 + i;  j++) {
                baos.write((byte) j);
            }
            baos.write("\r\n".getBytes(StandardCharsets.US_ASCII));
        }
        baos.write("-----1234--\r\n".getBytes(StandardCharsets.US_ASCII));
        final byte[] contents = baos.toByteArray();

        MockHttpServletRequest request = new MockHttpServletRequest(contents, Constants.CONTENT_TYPE);
        runTest(NUM_ITEMS, contents.length, request);
        request = new MockHttpServletRequest(contents, Constants.CONTENT_TYPE) {
            @Override
            public int getContentLength() {
                return -1;
            }
        };
        runTest(NUM_ITEMS, contents.length, request);
    }

    private void runTest(final int NUM_ITEMS, final long pContentLength, final MockHttpServletRequest request) throws FileUploadException, IOException {
// Path: src/main/java/org/apache/commons/fileupload2/servlet/ServletFileUpload.java
// public class ServletFileUpload extends FileUpload {
// 
//     /**
//      * Constant for HTTP POST method.
//      */
//     private static final String POST_METHOD = "POST";
// 
//     // ---------------------------------------------------------- Class methods
// 
//     /**
//      * Utility method that determines whether the request contains multipart
//      * content.
//      *
//      * @param request The servlet request to be evaluated. Must be non-null.
//      *
//      * @return {@code true} if the request is multipart;
//      *         {@code false} otherwise.
//      */
//     public static final boolean isMultipartContent(
//             final HttpServletRequest request) {
//         if (!POST_METHOD.equalsIgnoreCase(request.getMethod())) {
//             return false;
//         }
//         return FileUploadBase.isMultipartContent(new ServletRequestContext(request));
//     }
// 
//     // ----------------------------------------------------------- Constructors
// 
//     /**
//      * Constructs an uninitialized instance of this class. A factory must be
//      * configured, using {@code setFileItemFactory()}, before attempting
//      * to parse requests.
//      *
//      * @see FileUpload#FileUpload(FileItemFactory)
//      */
//     public ServletFileUpload() {
//     }
// 
//     /**
//      * Constructs an instance of this class which uses the supplied factory to
//      * create {@code FileItem} instances.
//      *
//      * @see FileUpload#FileUpload()
//      * @param fileItemFactory The factory to use for creating file items.
//      */
//     public ServletFileUpload(final FileItemFactory fileItemFactory) {
//         super(fileItemFactory);
//     }
// 
//     // --------------------------------------------------------- Public methods
// 
//     /**
//      * Processes an <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>
//      * compliant {@code multipart/form-data} stream.
//      *
//      * @param request The servlet request to be parsed.
//      *
//      * @return A list of {@code FileItem} instances parsed from the
//      *         request, in the order that they were transmitted.
//      *
//      * @throws FileUploadException if there are problems reading/parsing
//      *                             the request or storing files.
//      */
//     public List<FileItem> parseRequest(final HttpServletRequest request)
//     throws FileUploadException {
//         return parseRequest(new ServletRequestContext(request));
//     }
// 
//     /**
//      * Processes an <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>
//      * compliant {@code multipart/form-data} stream.
//      *
//      * @param request The servlet request to be parsed.
//      *
//      * @return A map of {@code FileItem} instances parsed from the request.
//      *
//      * @throws FileUploadException if there are problems reading/parsing
//      *                             the request or storing files.
//      *
//      * @since 1.3
//      */
//     public Map<String, List<FileItem>> parseParameterMap(final HttpServletRequest request)
//             throws FileUploadException {
//         return parseParameterMap(new ServletRequestContext(request));
//     }
// 
//     /**
//      * Processes an <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>
//      * compliant {@code multipart/form-data} stream.
//      *
//      * @param request The servlet request to be parsed.
//      *
//      * @return An iterator to instances of {@code FileItemStream}
//      *         parsed from the request, in the order that they were
//      *         transmitted.
//      *
//      * @throws FileUploadException if there are problems reading/parsing
//      *                             the request or storing files.
//      * @throws IOException An I/O error occurred. This may be a network
//      *   error while communicating with the client or a problem while
//      *   storing the uploaded content.
//      */
//     public FileItemIterator getItemIterator(final HttpServletRequest request)
//     throws FileUploadException, IOException {
//         return super.getItemIterator(new ServletRequestContext(request));
//     }
// 
// }


// Path: src/test/java/org/apache/commons/fileupload2/ProgressListenerTest.java
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import org.apache.commons.fileupload2.servlet.ServletFileUpload;
import org.junit.jupiter.api.Test;

     */
    @Test
    public void testProgressListener() throws Exception {
        final int NUM_ITEMS = 512;
        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
        for (int i = 0;  i < NUM_ITEMS;  i++) {
            final String header = "-----1234\r\n"
                + "Content-Disposition: form-data; name=\"field" + (i + 1) + "\"\r\n"
                + "\r\n";
            baos.write(header.getBytes(StandardCharsets.US_ASCII));
            for (int j = 0;  j < 16384 + i;  j++) {
                baos.write((byte) j);
            }
            baos.write("\r\n".getBytes(StandardCharsets.US_ASCII));
        }
        baos.write("-----1234--\r\n".getBytes(StandardCharsets.US_ASCII));
        final byte[] contents = baos.toByteArray();

        MockHttpServletRequest request = new MockHttpServletRequest(contents, Constants.CONTENT_TYPE);
        runTest(NUM_ITEMS, contents.length, request);
        request = new MockHttpServletRequest(contents, Constants.CONTENT_TYPE) {
            @Override
            public int getContentLength() {
                return -1;
            }
        };
        runTest(NUM_ITEMS, contents.length, request);
    }

    private void runTest(final int NUM_ITEMS, final long pContentLength, final MockHttpServletRequest request) throws FileUploadException, IOException {
        final ServletFileUpload upload = new ServletFileUpload();