001package Torello.Browser;
002
003import java.util.*;
004import javax.json.*;
005import javax.json.stream.*;
006import java.io.*;
007
008import java.lang.reflect.Method;
009import java.lang.reflect.Parameter;
010import java.util.function.Function;
011
012import Torello.Java.Additional.*;
013import Torello.Java.JSON.*;
014
015import static Torello.Java.JSON.JFlag.*;
016
017import Torello.Java.StrCmpr;
018import Torello.JavaDoc.StaticFunctional;
019import Torello.JavaDoc.JDHeaderBackgroundImg;
020import Torello.JavaDoc.Excuse;
021
022/**
023 * <SPAN CLASS=COPIEDJDK><B>A domain for letting clients substitute browser's network layer with client code.</B></SPAN>
024 * 
025 * <EMBED CLASS='external-html' DATA-FILE-ID=CODE_GEN_NOTE>
026 */
027@StaticFunctional(Excused={"counter"}, Excuses={Excuse.CONFIGURATION})
028@JDHeaderBackgroundImg(EmbedTagFileID="WOOD_PLANK_NOTE")
029public class Fetch
030{
031    // ********************************************************************************************
032    // ********************************************************************************************
033    // Class Header Stuff
034    // ********************************************************************************************
035    // ********************************************************************************************
036
037
038    // No Pubic Constructors
039    private Fetch () { }
040
041    // These two Vector's are used by all the "Methods" exported by this class.  java.lang.reflect
042    // is used to generate the JSON String's.  It saves thousands of lines of Auto-Generated Code.
043    private static final Map<String, Vector<String>>    parameterNames = new HashMap<>();
044    private static final Map<String, Vector<Class<?>>>  parameterTypes = new HashMap<>();
045
046    // Some Methods do not take any parameters - for instance all the "enable()" and "disable()"
047    // I simply could not get ride of RAW-TYPES and UNCHECKED warnings... so there are now,
048    // offically, two empty-vectors.  One for String's, and the other for Classes.
049
050    private static final Vector<String>     EMPTY_VEC_STR = new Vector<>();
051    private static final Vector<Class<?>>   EMPTY_VEC_CLASS = new Vector<>();
052
053    static
054    {
055        for (Method m : Fetch.class.getMethods())
056        {
057            // This doesn't work!  The parameter names are all "arg0" ... "argN"
058            // It works for java.lang.reflect.Field, BUT NOT java.lang.reflect.Parameter!
059            //
060            // Vector<String> parameterNamesList = new Vector<>(); -- NOPE!
061
062            Vector<Class<?>> parameterTypesList = new Vector<>();
063        
064            for (Parameter p : m.getParameters()) parameterTypesList.add(p.getType());
065
066            parameterTypes.put(
067                m.getName(),
068                (parameterTypesList.size() > 0) ? parameterTypesList : EMPTY_VEC_CLASS
069            );
070        }
071    }
072
073    static
074    {
075        Vector<String> v = null;
076
077        parameterNames.put("disable", EMPTY_VEC_STR);
078
079        v = new Vector<String>(2);
080        parameterNames.put("enable", v);
081        Collections.addAll(v, new String[]
082        { "patterns", "handleAuthRequests", });
083
084        v = new Vector<String>(2);
085        parameterNames.put("failRequest", v);
086        Collections.addAll(v, new String[]
087        { "requestId", "errorReason", });
088
089        v = new Vector<String>(6);
090        parameterNames.put("fulfillRequest", v);
091        Collections.addAll(v, new String[]
092        { "requestId", "responseCode", "responseHeaders", "binaryResponseHeaders", "body", "responsePhrase", });
093
094        v = new Vector<String>(6);
095        parameterNames.put("continueRequest", v);
096        Collections.addAll(v, new String[]
097        { "requestId", "url", "method", "postData", "headers", "interceptResponse", });
098
099        v = new Vector<String>(2);
100        parameterNames.put("continueWithAuth", v);
101        Collections.addAll(v, new String[]
102        { "requestId", "authChallengeResponse", });
103
104        v = new Vector<String>(5);
105        parameterNames.put("continueResponse", v);
106        Collections.addAll(v, new String[]
107        { "requestId", "responseCode", "responsePhrase", "responseHeaders", "binaryResponseHeaders", });
108
109        v = new Vector<String>(1);
110        parameterNames.put("getResponseBody", v);
111        Collections.addAll(v, new String[]
112        { "requestId", });
113
114        v = new Vector<String>(1);
115        parameterNames.put("takeResponseBodyAsStream", v);
116        Collections.addAll(v, new String[]
117        { "requestId", });
118    }
119
120
121    // ********************************************************************************************
122    // ********************************************************************************************
123    // Types - Static Inner Classes
124    // ********************************************************************************************
125    // ********************************************************************************************
126
127    // public static class RequestId => String
128    
129    /**
130     * Stages of the request to handle. Request will intercept before the request is
131     * sent. Response will intercept after the response is received (but before response
132     * body is received).
133     */
134    public static final String[] RequestStage =
135    { "Request", "Response", };
136    
137    /** <CODE>[No Description Provided by Google]</CODE> */
138    public static class RequestPattern
139        extends BaseType
140        implements java.io.Serializable
141    {
142        /** For Object Serialization.  java.io.Serializable */
143        protected static final long serialVersionUID = 1;
144        
145        public boolean[] optionals()
146        { return new boolean[] { true, true, true, }; }
147        
148        /**
149         * Wildcards (<CODE>'*'</CODE> -&gt; zero or more, <CODE>'?'</CODE> -&gt; exactly one) are allowed. Escape character is
150         * backslash. Omitting is equivalent to <CODE>"*"</CODE>.
151         * <BR />
152         * <BR /><B>OPTIONAL</B>
153         */
154        public final String urlPattern;
155        
156        /**
157         * If set, only requests for matching resource types will be intercepted.
158         * <BR />
159         * <BR /><B>OPTIONAL</B>
160         */
161        public final String resourceType;
162        
163        /**
164         * Stage at which to begin intercepting requests. Default is Request.
165         * <BR />
166         * <BR /><B>OPTIONAL</B>
167         */
168        public final String requestStage;
169        
170        /**
171         * Constructor
172         *
173         * @param urlPattern 
174         * Wildcards (<CODE>'*'</CODE> -&gt; zero or more, <CODE>'?'</CODE> -&gt; exactly one) are allowed. Escape character is
175         * backslash. Omitting is equivalent to <CODE>"*"</CODE>.
176         * <BR /><B>OPTIONAL</B>
177         * 
178         * @param resourceType If set, only requests for matching resource types will be intercepted.
179         * <BR /><B>OPTIONAL</B>
180         * 
181         * @param requestStage Stage at which to begin intercepting requests. Default is Request.
182         * <BR /><B>OPTIONAL</B>
183         */
184        public RequestPattern(String urlPattern, String resourceType, String requestStage)
185        {
186            // Exception-Check(s) to ensure that if any parameters which must adhere to a
187            // provided List of Enumerated Values, fails, then IllegalArgumentException shall throw.
188            
189            BRDPC.checkIAE("resourceType", resourceType, "Network.ResourceType", Network.ResourceType);
190            BRDPC.checkIAE("requestStage", requestStage, "Fetch.RequestStage", Fetch.RequestStage);
191            
192            this.urlPattern    = urlPattern;
193            this.resourceType  = resourceType;
194            this.requestStage  = requestStage;
195        }
196        
197        /**
198         * JSON Object Constructor
199         * @param jo A Json-Object having data about an instance of {@code 'RequestPattern'}.
200         */
201        public RequestPattern (JsonObject jo)
202        {
203            this.urlPattern    = ReadJSON.getString(jo, "urlPattern", true, false);
204            this.resourceType  = ReadJSON.getString(jo, "resourceType", true, false);
205            this.requestStage  = ReadJSON.getString(jo, "requestStage", true, false);
206        }
207        
208        
209        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
210        public boolean equals(Object other)
211        {
212            if (other == null)                       return false;
213            if (other.getClass() != this.getClass()) return false;
214        
215            RequestPattern o = (RequestPattern) other;
216        
217            return
218                    Objects.equals(this.urlPattern, o.urlPattern)
219                &&  Objects.equals(this.resourceType, o.resourceType)
220                &&  Objects.equals(this.requestStage, o.requestStage);
221        }
222        
223        /** Generates a Hash-Code for {@code 'this'} instance */
224        public int hashCode()
225        {
226            return
227                    Objects.hashCode(this.urlPattern)
228                +   Objects.hashCode(this.resourceType)
229                +   Objects.hashCode(this.requestStage);
230        }
231    }
232    
233    /** Response HTTP header entry */
234    public static class HeaderEntry
235        extends BaseType
236        implements java.io.Serializable
237    {
238        /** For Object Serialization.  java.io.Serializable */
239        protected static final long serialVersionUID = 1;
240        
241        public boolean[] optionals()
242        { return new boolean[] { false, false, }; }
243        
244        /** <CODE>[No Description Provided by Google]</CODE> */
245        public final String name;
246        
247        /** <CODE>[No Description Provided by Google]</CODE> */
248        public final String value;
249        
250        /**
251         * Constructor
252         *
253         * @param name -
254         * 
255         * @param value -
256         */
257        public HeaderEntry(String name, String value)
258        {
259            // Exception-Check(s) to ensure that if any parameters which are not declared as
260            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
261            
262            if (name == null)  BRDPC.throwNPE("name");
263            if (value == null) BRDPC.throwNPE("value");
264            
265            this.name   = name;
266            this.value  = value;
267        }
268        
269        /**
270         * JSON Object Constructor
271         * @param jo A Json-Object having data about an instance of {@code 'HeaderEntry'}.
272         */
273        public HeaderEntry (JsonObject jo)
274        {
275            this.name   = ReadJSON.getString(jo, "name", false, true);
276            this.value  = ReadJSON.getString(jo, "value", false, true);
277        }
278        
279        
280        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
281        public boolean equals(Object other)
282        {
283            if (other == null)                       return false;
284            if (other.getClass() != this.getClass()) return false;
285        
286            HeaderEntry o = (HeaderEntry) other;
287        
288            return
289                    Objects.equals(this.name, o.name)
290                &&  Objects.equals(this.value, o.value);
291        }
292        
293        /** Generates a Hash-Code for {@code 'this'} instance */
294        public int hashCode()
295        {
296            return
297                    Objects.hashCode(this.name)
298                +   Objects.hashCode(this.value);
299        }
300    }
301    
302    /** Authorization challenge for HTTP status code 401 or 407. */
303    public static class AuthChallenge
304        extends BaseType
305        implements java.io.Serializable
306    {
307        /** For Object Serialization.  java.io.Serializable */
308        protected static final long serialVersionUID = 1;
309        
310        public boolean[] optionals()
311        { return new boolean[] { true, false, false, false, }; }
312        
313        /**
314         * Source of the authentication challenge.
315         * <BR />
316         * <BR /><B>OPTIONAL</B>
317         */
318        public final String source;
319        
320        /** Origin of the challenger. */
321        public final String origin;
322        
323        /** The authentication scheme used, such as basic or digest */
324        public final String scheme;
325        
326        /** The realm of the challenge. May be empty. */
327        public final String realm;
328        
329        /**
330         * Constructor
331         *
332         * @param source Source of the authentication challenge.
333         * <BR />Acceptable Values: ["Server", "Proxy"]
334         * <BR /><B>OPTIONAL</B>
335         * 
336         * @param origin Origin of the challenger.
337         * 
338         * @param scheme The authentication scheme used, such as basic or digest
339         * 
340         * @param realm The realm of the challenge. May be empty.
341         */
342        public AuthChallenge(String source, String origin, String scheme, String realm)
343        {
344            // Exception-Check(s) to ensure that if any parameters which are not declared as
345            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
346            
347            if (origin == null) BRDPC.throwNPE("origin");
348            if (scheme == null) BRDPC.throwNPE("scheme");
349            if (realm == null)  BRDPC.throwNPE("realm");
350            
351            // Exception-Check(s) to ensure that if any parameters which must adhere to a
352            // provided List of Enumerated Values, fails, then IllegalArgumentException shall throw.
353            
354            BRDPC.checkIAE(
355                "source", source,
356                "Server", "Proxy"
357            );
358            
359            this.source  = source;
360            this.origin  = origin;
361            this.scheme  = scheme;
362            this.realm   = realm;
363        }
364        
365        /**
366         * JSON Object Constructor
367         * @param jo A Json-Object having data about an instance of {@code 'AuthChallenge'}.
368         */
369        public AuthChallenge (JsonObject jo)
370        {
371            this.source  = ReadJSON.getString(jo, "source", true, false);
372            this.origin  = ReadJSON.getString(jo, "origin", false, true);
373            this.scheme  = ReadJSON.getString(jo, "scheme", false, true);
374            this.realm   = ReadJSON.getString(jo, "realm", false, true);
375        }
376        
377        
378        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
379        public boolean equals(Object other)
380        {
381            if (other == null)                       return false;
382            if (other.getClass() != this.getClass()) return false;
383        
384            AuthChallenge o = (AuthChallenge) other;
385        
386            return
387                    Objects.equals(this.source, o.source)
388                &&  Objects.equals(this.origin, o.origin)
389                &&  Objects.equals(this.scheme, o.scheme)
390                &&  Objects.equals(this.realm, o.realm);
391        }
392        
393        /** Generates a Hash-Code for {@code 'this'} instance */
394        public int hashCode()
395        {
396            return
397                    Objects.hashCode(this.source)
398                +   Objects.hashCode(this.origin)
399                +   Objects.hashCode(this.scheme)
400                +   Objects.hashCode(this.realm);
401        }
402    }
403    
404    /** Response to an AuthChallenge. */
405    public static class AuthChallengeResponse
406        extends BaseType
407        implements java.io.Serializable
408    {
409        /** For Object Serialization.  java.io.Serializable */
410        protected static final long serialVersionUID = 1;
411        
412        public boolean[] optionals()
413        { return new boolean[] { false, true, true, }; }
414        
415        /**
416         * The decision on what to do in response to the authorization challenge.  Default means
417         * deferring to the default behavior of the net stack, which will likely either the Cancel
418         * authentication or display a popup dialog box.
419         */
420        public final String response;
421        
422        /**
423         * The username to provide, possibly empty. Should only be set if response is
424         * ProvideCredentials.
425         * <BR />
426         * <BR /><B>OPTIONAL</B>
427         */
428        public final String username;
429        
430        /**
431         * The password to provide, possibly empty. Should only be set if response is
432         * ProvideCredentials.
433         * <BR />
434         * <BR /><B>OPTIONAL</B>
435         */
436        public final String password;
437        
438        /**
439         * Constructor
440         *
441         * @param response 
442         * The decision on what to do in response to the authorization challenge.  Default means
443         * deferring to the default behavior of the net stack, which will likely either the Cancel
444         * authentication or display a popup dialog box.
445         * <BR />Acceptable Values: ["Default", "CancelAuth", "ProvideCredentials"]
446         * 
447         * @param username 
448         * The username to provide, possibly empty. Should only be set if response is
449         * ProvideCredentials.
450         * <BR /><B>OPTIONAL</B>
451         * 
452         * @param password 
453         * The password to provide, possibly empty. Should only be set if response is
454         * ProvideCredentials.
455         * <BR /><B>OPTIONAL</B>
456         */
457        public AuthChallengeResponse(String response, String username, String password)
458        {
459            // Exception-Check(s) to ensure that if any parameters which are not declared as
460            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
461            
462            if (response == null) BRDPC.throwNPE("response");
463            
464            // Exception-Check(s) to ensure that if any parameters which must adhere to a
465            // provided List of Enumerated Values, fails, then IllegalArgumentException shall throw.
466            
467            BRDPC.checkIAE(
468                "response", response,
469                "Default", "CancelAuth", "ProvideCredentials"
470            );
471            
472            this.response  = response;
473            this.username  = username;
474            this.password  = password;
475        }
476        
477        /**
478         * JSON Object Constructor
479         * @param jo A Json-Object having data about an instance of {@code 'AuthChallengeResponse'}.
480         */
481        public AuthChallengeResponse (JsonObject jo)
482        {
483            this.response  = ReadJSON.getString(jo, "response", false, true);
484            this.username  = ReadJSON.getString(jo, "username", true, false);
485            this.password  = ReadJSON.getString(jo, "password", true, false);
486        }
487        
488        
489        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
490        public boolean equals(Object other)
491        {
492            if (other == null)                       return false;
493            if (other.getClass() != this.getClass()) return false;
494        
495            AuthChallengeResponse o = (AuthChallengeResponse) other;
496        
497            return
498                    Objects.equals(this.response, o.response)
499                &&  Objects.equals(this.username, o.username)
500                &&  Objects.equals(this.password, o.password);
501        }
502        
503        /** Generates a Hash-Code for {@code 'this'} instance */
504        public int hashCode()
505        {
506            return
507                    Objects.hashCode(this.response)
508                +   Objects.hashCode(this.username)
509                +   Objects.hashCode(this.password);
510        }
511    }
512    
513    /**
514     * Issued when the domain is enabled and the request URL matches the
515     * specified filter. The request is paused until the client responds
516     * with one of continueRequest, failRequest or fulfillRequest.
517     * The stage of the request can be determined by presence of responseErrorReason
518     * and responseStatusCode -- the request is at the response stage if either
519     * of these fields is present and in the request stage otherwise.
520     */
521    public static class requestPaused
522        extends BrowserEvent
523        implements java.io.Serializable
524    {
525        /** For Object Serialization.  java.io.Serializable */
526        protected static final long serialVersionUID = 1;
527        
528        public boolean[] optionals()
529        { return new boolean[] { false, false, false, false, true, true, true, true, true, }; }
530        
531        /** Each request the page makes will have a unique id. */
532        public final String requestId;
533        
534        /** The details of the request. */
535        public final Network.Request request;
536        
537        /** The id of the frame that initiated the request. */
538        public final String frameId;
539        
540        /** How the requested resource will be used. */
541        public final String resourceType;
542        
543        /**
544         * Response error if intercepted at response stage.
545         * <BR />
546         * <BR /><B>OPTIONAL</B>
547         */
548        public final String responseErrorReason;
549        
550        /**
551         * Response code if intercepted at response stage.
552         * <BR />
553         * <BR /><B>OPTIONAL</B>
554         */
555        public final Integer responseStatusCode;
556        
557        /**
558         * Response status text if intercepted at response stage.
559         * <BR />
560         * <BR /><B>OPTIONAL</B>
561         */
562        public final String responseStatusText;
563        
564        /**
565         * Response headers if intercepted at the response stage.
566         * <BR />
567         * <BR /><B>OPTIONAL</B>
568         */
569        public final Fetch.HeaderEntry[] responseHeaders;
570        
571        /**
572         * If the intercepted request had a corresponding Network.requestWillBeSent event fired for it,
573         * then this networkId will be the same as the requestId present in the requestWillBeSent event.
574         * <BR />
575         * <BR /><B>OPTIONAL</B>
576         */
577        public final String networkId;
578        
579        /**
580         * Constructor
581         *
582         * @param requestId Each request the page makes will have a unique id.
583         * 
584         * @param request The details of the request.
585         * 
586         * @param frameId The id of the frame that initiated the request.
587         * 
588         * @param resourceType How the requested resource will be used.
589         * 
590         * @param responseErrorReason Response error if intercepted at response stage.
591         * <BR /><B>OPTIONAL</B>
592         * 
593         * @param responseStatusCode Response code if intercepted at response stage.
594         * <BR /><B>OPTIONAL</B>
595         * 
596         * @param responseStatusText Response status text if intercepted at response stage.
597         * <BR /><B>OPTIONAL</B>
598         * 
599         * @param responseHeaders Response headers if intercepted at the response stage.
600         * <BR /><B>OPTIONAL</B>
601         * 
602         * @param networkId 
603         * If the intercepted request had a corresponding Network.requestWillBeSent event fired for it,
604         * then this networkId will be the same as the requestId present in the requestWillBeSent event.
605         * <BR /><B>OPTIONAL</B>
606         */
607        public requestPaused(
608                String requestId, Network.Request request, String frameId, String resourceType, 
609                String responseErrorReason, Integer responseStatusCode, String responseStatusText, 
610                Fetch.HeaderEntry[] responseHeaders, String networkId
611            )
612        {
613            super("Fetch", "requestPaused", 9);
614            
615            // Exception-Check(s) to ensure that if any parameters which are not declared as
616            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
617            
618            if (requestId == null)    BRDPC.throwNPE("requestId");
619            if (request == null)      BRDPC.throwNPE("request");
620            if (frameId == null)      BRDPC.throwNPE("frameId");
621            if (resourceType == null) BRDPC.throwNPE("resourceType");
622            
623            // Exception-Check(s) to ensure that if any parameters which must adhere to a
624            // provided List of Enumerated Values, fails, then IllegalArgumentException shall throw.
625            
626            BRDPC.checkIAE("resourceType", resourceType, "Network.ResourceType", Network.ResourceType);
627            BRDPC.checkIAE("responseErrorReason", responseErrorReason, "Network.ErrorReason", Network.ErrorReason);
628            
629            this.requestId            = requestId;
630            this.request              = request;
631            this.frameId              = frameId;
632            this.resourceType         = resourceType;
633            this.responseErrorReason  = responseErrorReason;
634            this.responseStatusCode   = responseStatusCode;
635            this.responseStatusText   = responseStatusText;
636            this.responseHeaders      = responseHeaders;
637            this.networkId            = networkId;
638        }
639        
640        /**
641         * JSON Object Constructor
642         * @param jo A Json-Object having data about an instance of {@code 'requestPaused'}.
643         */
644        public requestPaused (JsonObject jo)
645        {
646            super("Fetch", "requestPaused", 9);
647        
648            this.requestId            = ReadJSON.getString(jo, "requestId", false, true);
649            this.request              = ReadJSON.getObject(jo, "request", Network.Request.class, false, true);
650            this.frameId              = ReadJSON.getString(jo, "frameId", false, true);
651            this.resourceType         = ReadJSON.getString(jo, "resourceType", false, true);
652            this.responseErrorReason  = ReadJSON.getString(jo, "responseErrorReason", true, false);
653            this.responseStatusCode   = ReadBoxedJSON.getInteger(jo, "responseStatusCode", true);
654            this.responseStatusText   = ReadJSON.getString(jo, "responseStatusText", true, false);
655            this.responseHeaders = (jo.getJsonArray("responseHeaders") == null)
656                ? null
657                : ReadArrJSON.DimN.objArr(jo.getJsonArray("responseHeaders"), null, 0, Fetch.HeaderEntry[].class);
658        
659            this.networkId            = ReadJSON.getString(jo, "networkId", true, false);
660        }
661        
662        
663        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
664        public boolean equals(Object other)
665        {
666            if (other == null)                       return false;
667            if (other.getClass() != this.getClass()) return false;
668        
669            requestPaused o = (requestPaused) other;
670        
671            return
672                    Objects.equals(this.requestId, o.requestId)
673                &&  Objects.equals(this.request, o.request)
674                &&  Objects.equals(this.frameId, o.frameId)
675                &&  Objects.equals(this.resourceType, o.resourceType)
676                &&  Objects.equals(this.responseErrorReason, o.responseErrorReason)
677                &&  Objects.equals(this.responseStatusCode, o.responseStatusCode)
678                &&  Objects.equals(this.responseStatusText, o.responseStatusText)
679                &&  Arrays.deepEquals(this.responseHeaders, o.responseHeaders)
680                &&  Objects.equals(this.networkId, o.networkId);
681        }
682        
683        /** Generates a Hash-Code for {@code 'this'} instance */
684        public int hashCode()
685        {
686            return
687                    Objects.hashCode(this.requestId)
688                +   this.request.hashCode()
689                +   Objects.hashCode(this.frameId)
690                +   Objects.hashCode(this.resourceType)
691                +   Objects.hashCode(this.responseErrorReason)
692                +   Objects.hashCode(this.responseStatusCode)
693                +   Objects.hashCode(this.responseStatusText)
694                +   Arrays.deepHashCode(this.responseHeaders)
695                +   Objects.hashCode(this.networkId);
696        }
697    }
698    
699    /**
700     * Issued when the domain is enabled with handleAuthRequests set to true.
701     * The request is paused until client responds with continueWithAuth.
702     */
703    public static class authRequired
704        extends BrowserEvent
705        implements java.io.Serializable
706    {
707        /** For Object Serialization.  java.io.Serializable */
708        protected static final long serialVersionUID = 1;
709        
710        public boolean[] optionals()
711        { return new boolean[] { false, false, false, false, false, }; }
712        
713        /** Each request the page makes will have a unique id. */
714        public final String requestId;
715        
716        /** The details of the request. */
717        public final Network.Request request;
718        
719        /** The id of the frame that initiated the request. */
720        public final String frameId;
721        
722        /** How the requested resource will be used. */
723        public final String resourceType;
724        
725        /**
726         * Details of the Authorization Challenge encountered.
727         * If this is set, client should respond with continueRequest that
728         * contains AuthChallengeResponse.
729         */
730        public final Fetch.AuthChallenge authChallenge;
731        
732        /**
733         * Constructor
734         *
735         * @param requestId Each request the page makes will have a unique id.
736         * 
737         * @param request The details of the request.
738         * 
739         * @param frameId The id of the frame that initiated the request.
740         * 
741         * @param resourceType How the requested resource will be used.
742         * 
743         * @param authChallenge 
744         * Details of the Authorization Challenge encountered.
745         * If this is set, client should respond with continueRequest that
746         * contains AuthChallengeResponse.
747         */
748        public authRequired(
749                String requestId, Network.Request request, String frameId, String resourceType, 
750                Fetch.AuthChallenge authChallenge
751            )
752        {
753            super("Fetch", "authRequired", 5);
754            
755            // Exception-Check(s) to ensure that if any parameters which are not declared as
756            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
757            
758            if (requestId == null)     BRDPC.throwNPE("requestId");
759            if (request == null)       BRDPC.throwNPE("request");
760            if (frameId == null)       BRDPC.throwNPE("frameId");
761            if (resourceType == null)  BRDPC.throwNPE("resourceType");
762            if (authChallenge == null) BRDPC.throwNPE("authChallenge");
763            
764            // Exception-Check(s) to ensure that if any parameters which must adhere to a
765            // provided List of Enumerated Values, fails, then IllegalArgumentException shall throw.
766            
767            BRDPC.checkIAE("resourceType", resourceType, "Network.ResourceType", Network.ResourceType);
768            
769            this.requestId      = requestId;
770            this.request        = request;
771            this.frameId        = frameId;
772            this.resourceType   = resourceType;
773            this.authChallenge  = authChallenge;
774        }
775        
776        /**
777         * JSON Object Constructor
778         * @param jo A Json-Object having data about an instance of {@code 'authRequired'}.
779         */
780        public authRequired (JsonObject jo)
781        {
782            super("Fetch", "authRequired", 5);
783        
784            this.requestId      = ReadJSON.getString(jo, "requestId", false, true);
785            this.request        = ReadJSON.getObject(jo, "request", Network.Request.class, false, true);
786            this.frameId        = ReadJSON.getString(jo, "frameId", false, true);
787            this.resourceType   = ReadJSON.getString(jo, "resourceType", false, true);
788            this.authChallenge  = ReadJSON.getObject(jo, "authChallenge", Fetch.AuthChallenge.class, false, true);
789        }
790        
791        
792        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
793        public boolean equals(Object other)
794        {
795            if (other == null)                       return false;
796            if (other.getClass() != this.getClass()) return false;
797        
798            authRequired o = (authRequired) other;
799        
800            return
801                    Objects.equals(this.requestId, o.requestId)
802                &&  Objects.equals(this.request, o.request)
803                &&  Objects.equals(this.frameId, o.frameId)
804                &&  Objects.equals(this.resourceType, o.resourceType)
805                &&  Objects.equals(this.authChallenge, o.authChallenge);
806        }
807        
808        /** Generates a Hash-Code for {@code 'this'} instance */
809        public int hashCode()
810        {
811            return
812                    Objects.hashCode(this.requestId)
813                +   this.request.hashCode()
814                +   Objects.hashCode(this.frameId)
815                +   Objects.hashCode(this.resourceType)
816                +   this.authChallenge.hashCode();
817        }
818    }
819    
820    
821    // Counter for keeping the WebSocket Request ID's distinct.
822    private static int counter = 1;
823    
824    /**
825     * Disables the fetch domain.
826     * 
827     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
828     * {@link Ret0}&gt;</CODE>
829     *
830     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
831     * browser receives the invocation-request.
832     *
833     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
834     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
835     * {@code >} to ensure the Browser Function has run to completion.
836     */
837    public static Script<String, JsonObject, Ret0> disable()
838    {
839        final int          webSocketID = 42000000 + counter++;
840        final boolean[]    optionals   = new boolean[0];
841        
842        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
843        String requestJSON = WriteJSON.get(
844            parameterTypes.get("disable"),
845            parameterNames.get("disable"),
846            optionals, webSocketID,
847            "Fetch.disable"
848        );
849        
850        // This Remote Command does not have a Return-Value.
851        return new Script<>
852            (BRDPC.defaultSender, webSocketID, requestJSON, BRDPC.NoReturnValues);
853    }
854    
855    /**
856     * Enables issuing of requestPaused events. A request will be paused until client
857     * calls one of failRequest, fulfillRequest or continueRequest/continueWithAuth.
858     * 
859     * @param patterns 
860     * If specified, only requests matching any of these patterns will produce
861     * fetchRequested event and will be paused until clients response. If not set,
862     * all requests will be affected.
863     * <BR /><B>OPTIONAL</B>
864     * 
865     * @param handleAuthRequests 
866     * If true, authRequired events will be issued and requests will be paused
867     * expecting a call to continueWithAuth.
868     * <BR /><B>OPTIONAL</B>
869     * 
870     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
871     * {@link Ret0}&gt;</CODE>
872     *
873     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
874     * browser receives the invocation-request.
875     *
876     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
877     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
878     * {@code >} to ensure the Browser Function has run to completion.
879     */
880    public static Script<String, JsonObject, Ret0> enable
881        (Fetch.RequestPattern[] patterns, Boolean handleAuthRequests)
882    {
883        final int       webSocketID = 42001000 + counter++;
884        final boolean[] optionals   = { true, true, };
885        
886        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
887        String requestJSON = WriteJSON.get(
888            parameterTypes.get("enable"),
889            parameterNames.get("enable"),
890            optionals, webSocketID,
891            "Fetch.enable",
892            patterns, handleAuthRequests
893        );
894        
895        // This Remote Command does not have a Return-Value.
896        return new Script<>
897            (BRDPC.defaultSender, webSocketID, requestJSON, BRDPC.NoReturnValues);
898    }
899    
900    /**
901     * Causes the request to fail with specified reason.
902     * 
903     * @param requestId An id the client received in requestPaused event.
904     * 
905     * @param errorReason Causes the request to fail with the given reason.
906     * 
907     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
908     * {@link Ret0}&gt;</CODE>
909     *
910     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
911     * browser receives the invocation-request.
912     *
913     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
914     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
915     * {@code >} to ensure the Browser Function has run to completion.
916     */
917    public static Script<String, JsonObject, Ret0> failRequest
918        (String requestId, String errorReason)
919    {
920        // Exception-Check(s) to ensure that if any parameters which are not declared as
921        // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
922        
923        if (requestId == null)   BRDPC.throwNPE("requestId");
924        if (errorReason == null) BRDPC.throwNPE("errorReason");
925        
926        // Exception-Check(s) to ensure that if any parameters which must adhere to a
927        // provided List of Enumerated Values, fails, then IllegalArgumentException shall throw.
928        
929        BRDPC.checkIAE("errorReason", errorReason, "Network.ErrorReason", Network.ErrorReason);
930        
931        final int       webSocketID = 42002000 + counter++;
932        final boolean[] optionals   = { false, false, };
933        
934        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
935        String requestJSON = WriteJSON.get(
936            parameterTypes.get("failRequest"),
937            parameterNames.get("failRequest"),
938            optionals, webSocketID,
939            "Fetch.failRequest",
940            requestId, errorReason
941        );
942        
943        // This Remote Command does not have a Return-Value.
944        return new Script<>
945            (BRDPC.defaultSender, webSocketID, requestJSON, BRDPC.NoReturnValues);
946    }
947    
948    /**
949     * Provides response to the request.
950     * 
951     * @param requestId An id the client received in requestPaused event.
952     * 
953     * @param responseCode An HTTP response code.
954     * 
955     * @param responseHeaders Response headers.
956     * <BR /><B>OPTIONAL</B>
957     * 
958     * @param binaryResponseHeaders 
959     * Alternative way of specifying response headers as a \0-separated
960     * series of name: value pairs. Prefer the above method unless you
961     * need to represent some non-UTF8 values that can't be transmitted
962     * over the protocol as text. (Encoded as a base64 string when passed over JSON)
963     * <BR /><B>OPTIONAL</B>
964     * 
965     * @param body 
966     * A response body. If absent, original response body will be used if
967     * the request is intercepted at the response stage and empty body
968     * will be used if the request is intercepted at the request stage. (Encoded as a base64 string when passed over JSON)
969     * <BR /><B>OPTIONAL</B>
970     * 
971     * @param responsePhrase 
972     * A textual representation of responseCode.
973     * If absent, a standard phrase matching responseCode is used.
974     * <BR /><B>OPTIONAL</B>
975     * 
976     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
977     * {@link Ret0}&gt;</CODE>
978     *
979     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
980     * browser receives the invocation-request.
981     *
982     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
983     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
984     * {@code >} to ensure the Browser Function has run to completion.
985     */
986    public static Script<String, JsonObject, Ret0> fulfillRequest(
987            String requestId, int responseCode, Fetch.HeaderEntry[] responseHeaders, 
988            String binaryResponseHeaders, String body, String responsePhrase
989        )
990    {
991        // Exception-Check(s) to ensure that if any parameters which are not declared as
992        // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
993        
994        if (requestId == null) BRDPC.throwNPE("requestId");
995        
996        final int       webSocketID = 42003000 + counter++;
997        final boolean[] optionals   = { false, false, true, true, true, true, };
998        
999        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
1000        String requestJSON = WriteJSON.get(
1001            parameterTypes.get("fulfillRequest"),
1002            parameterNames.get("fulfillRequest"),
1003            optionals, webSocketID,
1004            "Fetch.fulfillRequest",
1005            requestId, responseCode, responseHeaders, binaryResponseHeaders, body, responsePhrase
1006        );
1007        
1008        // This Remote Command does not have a Return-Value.
1009        return new Script<>
1010            (BRDPC.defaultSender, webSocketID, requestJSON, BRDPC.NoReturnValues);
1011    }
1012    
1013    /**
1014     * Continues the request, optionally modifying some of its parameters.
1015     * 
1016     * @param requestId An id the client received in requestPaused event.
1017     * 
1018     * @param url If set, the request url will be modified in a way that's not observable by page.
1019     * <BR /><B>OPTIONAL</B>
1020     * 
1021     * @param method If set, the request method is overridden.
1022     * <BR /><B>OPTIONAL</B>
1023     * 
1024     * @param postData If set, overrides the post data in the request. (Encoded as a base64 string when passed over JSON)
1025     * <BR /><B>OPTIONAL</B>
1026     * 
1027     * @param headers If set, overrides the request headers.
1028     * <BR /><B>OPTIONAL</B>
1029     * 
1030     * @param interceptResponse If set, overrides response interception behavior for this request.
1031     * <BR /><B>OPTIONAL</B>
1032     * <BR /><B>EXPERIMENTAL</B>
1033     * 
1034     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
1035     * {@link Ret0}&gt;</CODE>
1036     *
1037     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
1038     * browser receives the invocation-request.
1039     *
1040     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
1041     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
1042     * {@code >} to ensure the Browser Function has run to completion.
1043     */
1044    public static Script<String, JsonObject, Ret0> continueRequest(
1045            String requestId, String url, String method, String postData, 
1046            Fetch.HeaderEntry[] headers, Boolean interceptResponse
1047        )
1048    {
1049        // Exception-Check(s) to ensure that if any parameters which are not declared as
1050        // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
1051        
1052        if (requestId == null) BRDPC.throwNPE("requestId");
1053        
1054        final int       webSocketID = 42004000 + counter++;
1055        final boolean[] optionals   = { false, true, true, true, true, true, };
1056        
1057        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
1058        String requestJSON = WriteJSON.get(
1059            parameterTypes.get("continueRequest"),
1060            parameterNames.get("continueRequest"),
1061            optionals, webSocketID,
1062            "Fetch.continueRequest",
1063            requestId, url, method, postData, headers, interceptResponse
1064        );
1065        
1066        // This Remote Command does not have a Return-Value.
1067        return new Script<>
1068            (BRDPC.defaultSender, webSocketID, requestJSON, BRDPC.NoReturnValues);
1069    }
1070    
1071    /**
1072     * Continues a request supplying authChallengeResponse following authRequired event.
1073     * 
1074     * @param requestId An id the client received in authRequired event.
1075     * 
1076     * @param authChallengeResponse Response to  with an authChallenge.
1077     * 
1078     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
1079     * {@link Ret0}&gt;</CODE>
1080     *
1081     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
1082     * browser receives the invocation-request.
1083     *
1084     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
1085     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
1086     * {@code >} to ensure the Browser Function has run to completion.
1087     */
1088    public static Script<String, JsonObject, Ret0> continueWithAuth
1089        (String requestId, Fetch.AuthChallengeResponse authChallengeResponse)
1090    {
1091        // Exception-Check(s) to ensure that if any parameters which are not declared as
1092        // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
1093        
1094        if (requestId == null)             BRDPC.throwNPE("requestId");
1095        if (authChallengeResponse == null) BRDPC.throwNPE("authChallengeResponse");
1096        
1097        final int       webSocketID = 42005000 + counter++;
1098        final boolean[] optionals   = { false, false, };
1099        
1100        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
1101        String requestJSON = WriteJSON.get(
1102            parameterTypes.get("continueWithAuth"),
1103            parameterNames.get("continueWithAuth"),
1104            optionals, webSocketID,
1105            "Fetch.continueWithAuth",
1106            requestId, authChallengeResponse
1107        );
1108        
1109        // This Remote Command does not have a Return-Value.
1110        return new Script<>
1111            (BRDPC.defaultSender, webSocketID, requestJSON, BRDPC.NoReturnValues);
1112    }
1113    
1114    /**
1115     * Continues loading of the paused response, optionally modifying the
1116     * response headers. If either responseCode or headers are modified, all of them
1117     * must be present.
1118     * <BR /><B>EXPERIMENTAL</B>
1119     * 
1120     * @param requestId An id the client received in requestPaused event.
1121     * 
1122     * @param responseCode An HTTP response code. If absent, original response code will be used.
1123     * <BR /><B>OPTIONAL</B>
1124     * 
1125     * @param responsePhrase 
1126     * A textual representation of responseCode.
1127     * If absent, a standard phrase matching responseCode is used.
1128     * <BR /><B>OPTIONAL</B>
1129     * 
1130     * @param responseHeaders Response headers. If absent, original response headers will be used.
1131     * <BR /><B>OPTIONAL</B>
1132     * 
1133     * @param binaryResponseHeaders 
1134     * Alternative way of specifying response headers as a \0-separated
1135     * series of name: value pairs. Prefer the above method unless you
1136     * need to represent some non-UTF8 values that can't be transmitted
1137     * over the protocol as text. (Encoded as a base64 string when passed over JSON)
1138     * <BR /><B>OPTIONAL</B>
1139     * 
1140     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
1141     * {@link Ret0}&gt;</CODE>
1142     *
1143     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
1144     * browser receives the invocation-request.
1145     *
1146     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
1147     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
1148     * {@code >} to ensure the Browser Function has run to completion.
1149     */
1150    public static Script<String, JsonObject, Ret0> continueResponse(
1151            String requestId, Integer responseCode, String responsePhrase, 
1152            Fetch.HeaderEntry[] responseHeaders, String binaryResponseHeaders
1153        )
1154    {
1155        // Exception-Check(s) to ensure that if any parameters which are not declared as
1156        // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
1157        
1158        if (requestId == null) BRDPC.throwNPE("requestId");
1159        
1160        final int       webSocketID = 42006000 + counter++;
1161        final boolean[] optionals   = { false, true, true, true, true, };
1162        
1163        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
1164        String requestJSON = WriteJSON.get(
1165            parameterTypes.get("continueResponse"),
1166            parameterNames.get("continueResponse"),
1167            optionals, webSocketID,
1168            "Fetch.continueResponse",
1169            requestId, responseCode, responsePhrase, responseHeaders, binaryResponseHeaders
1170        );
1171        
1172        // This Remote Command does not have a Return-Value.
1173        return new Script<>
1174            (BRDPC.defaultSender, webSocketID, requestJSON, BRDPC.NoReturnValues);
1175    }
1176    
1177    /**
1178     * Causes the body of the response to be received from the server and
1179     * returned as a single string. May only be issued for a request that
1180     * is paused in the Response stage and is mutually exclusive with
1181     * takeResponseBodyForInterceptionAsStream. Calling other methods that
1182     * affect the request or disabling fetch domain before body is received
1183     * results in an undefined behavior.
1184     * 
1185     * @param requestId Identifier for the intercepted request to get body for.
1186     * 
1187     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
1188     * {@link Ret2}&gt;</CODE>
1189     *
1190     * <BR /><BR />This {@link Script} may be <B STYLE='color:red'>executed</B> (using 
1191     * {@link Script#exec()}), and a {@link Promise} returned.
1192     *
1193     * <BR /><BR />When the {@code Promise} is <B STYLE='color: red'>awaited</B>
1194     * (using {@link Promise#await()}), the {@code Ret2} will subsequently
1195     * be returned from that call.
1196     * 
1197     * <BR /><BR />The <B STYLE='color: red'>returned</B> values are encapsulated
1198     * in an instance of <B>{@link Ret2}</B>
1199     *
1200     * <BR /><BR /><UL CLASS=JDUL>
1201     * <LI><CODE><B>Ret2.a:</B> String (<B>body</B>)</CODE>
1202     *     <BR />Response body.
1203     *     <BR /><BR /></LI>
1204     * <LI><CODE><B>Ret2.b:</B> Boolean (<B>base64Encoded</B>)</CODE>
1205     *     <BR />True, if content was sent as base64.
1206     *     </LI>
1207     * </UL>
1208     */
1209    public static Script<String, JsonObject, Ret2<String, Boolean>> getResponseBody
1210        (String requestId)
1211    {
1212        // Exception-Check(s) to ensure that if any parameters which are not declared as
1213        // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
1214        
1215        if (requestId == null) BRDPC.throwNPE("requestId");
1216        
1217        final int       webSocketID = 42007000 + counter++;
1218        final boolean[] optionals   = { false, };
1219        
1220        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
1221        String requestJSON = WriteJSON.get(
1222            parameterTypes.get("getResponseBody"),
1223            parameterNames.get("getResponseBody"),
1224            optionals, webSocketID,
1225            "Fetch.getResponseBody",
1226            requestId
1227        );
1228        
1229        // 'JSON Binding' ... Converts Browser Response-JSON into Java-Type 'Ret2'
1230        Function<JsonObject, Ret2<String, Boolean>> 
1231            responseProcessor = (JsonObject jo) -> new Ret2<>(
1232                ReadJSON.getString(jo, "body", false, true),
1233                ReadBoxedJSON.getBoolean(jo, "base64Encoded", true)
1234            );
1235        
1236        // Pass the 'defaultSender' to Script-Constructor
1237        // The sender that is used can be changed before executing script.
1238        return new Script<>(BRDPC.defaultSender, webSocketID, requestJSON, responseProcessor);
1239    }
1240    
1241    /**
1242     * Returns a handle to the stream representing the response body.
1243     * The request must be paused in the HeadersReceived stage.
1244     * Note that after this command the request can't be continued
1245     * as is -- client either needs to cancel it or to provide the
1246     * response body.
1247     * The stream only supports sequential read, IO.read will fail if the position
1248     * is specified.
1249     * This method is mutually exclusive with getResponseBody.
1250     * Calling other methods that affect the request or disabling fetch
1251     * domain before body is received results in an undefined behavior.
1252     * 
1253     * @param requestId -
1254     * 
1255     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
1256     * String&gt;</CODE>
1257     * 
1258     * <BR /><BR />This <B>script</B> may be <B STYLE='color: red'>executed</B>, using
1259     * {@link Script#exec()}, and afterwards, a {@link Promise}<CODE>&lt;JsonObject,
1260     * String&gt;</CODE> will be returned.
1261     *
1262     * <BR /><BR />Finally, the <B>{@code Promise}</B> may be <B STYLE='color: red'>awaited</B>,
1263     * using {@link Promise#await()}, <I>and the returned result of this Browser Function may
1264      * may be retrieved.</I>
1265     *
1266     * <BR /><BR />This Browser Function <B STYLE='color: red'>returns</B>
1267     * <BR /><BR /><UL CLASS=JDUL>
1268     * <LI><CODE>String (<B>stream</B></CODE>)
1269     *     <BR />-
1270     * </LI>
1271     * </UL> */
1272    public static Script<String, JsonObject, String> takeResponseBodyAsStream(String requestId)
1273    {
1274        // Exception-Check(s) to ensure that if any parameters which are not declared as
1275        // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
1276        
1277        if (requestId == null) BRDPC.throwNPE("requestId");
1278        
1279        final int       webSocketID = 42008000 + counter++;
1280        final boolean[] optionals   = { false, };
1281        
1282        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
1283        String requestJSON = WriteJSON.get(
1284            parameterTypes.get("takeResponseBodyAsStream"),
1285            parameterNames.get("takeResponseBodyAsStream"),
1286            optionals, webSocketID,
1287            "Fetch.takeResponseBodyAsStream",
1288            requestId
1289        );
1290        
1291        // 'JSON Binding' ... Converts Browser Response-JSON to 'String'
1292        Function<JsonObject, String> responseProcessor = (JsonObject jo) ->
1293            ReadJSON.getString(jo, "stream", false, true);
1294        
1295        // Pass the 'defaultSender' to Script-Constructor
1296        // The sender that is used can be changed before executing script.
1297        return new Script<>(BRDPC.defaultSender, webSocketID, requestJSON, responseProcessor);
1298    }
1299    
1300}