View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.juneau.rest.test.client;
18  
19  import static org.apache.juneau.TestUtils.*;
20  import static org.apache.juneau.http.HttpHeaders.*;
21  import static org.apache.juneau.http.HttpParts.*;
22  import static org.apache.juneau.utest.utils.Constants.*;
23  import static org.junit.jupiter.api.Assertions.*;
24  
25  import java.util.*;
26  
27  import org.apache.juneau.*;
28  import org.apache.juneau.annotation.*;
29  import org.apache.juneau.html.*;
30  import org.apache.juneau.http.annotation.*;
31  import org.apache.juneau.http.header.*;
32  import org.apache.juneau.http.part.*;
33  import org.apache.juneau.http.remote.*;
34  import org.apache.juneau.httppart.*;
35  import org.apache.juneau.json.*;
36  import org.apache.juneau.msgpack.*;
37  import org.apache.juneau.parser.*;
38  import org.apache.juneau.rest.mock.*;
39  import org.apache.juneau.serializer.*;
40  import org.apache.juneau.testutils.pojos.*;
41  import org.apache.juneau.uon.*;
42  import org.apache.juneau.urlencoding.*;
43  import org.apache.juneau.xml.*;
44  import org.junit.jupiter.params.*;
45  import org.junit.jupiter.params.provider.*;
46  import org.opentest4j.*;
47  
48  class ThirdPartyProxy_Test extends TestBase {
49  
50  	private static final Input[] INPUT = {
51  		input("Json", JsonSerializer.DEFAULT.copy().addBeanTypes().addRootType().build(), JsonParser.DEFAULT),
52  		input("Xml", XmlSerializer.DEFAULT.copy().addBeanTypes().addRootType().build(), XmlParser.DEFAULT),
53  		input("Mixed", JsonSerializer.DEFAULT.copy().addBeanTypes().addRootType().build(), XmlParser.DEFAULT),
54  		input("Html", HtmlSerializer.DEFAULT.copy().addBeanTypes().addRootType().build(), HtmlParser.DEFAULT),
55  		input("MessagePack", MsgPackSerializer.DEFAULT.copy().addBeanTypes().addRootType().build(), MsgPackParser.DEFAULT),
56  		input("UrlEncoding", UrlEncodingSerializer.DEFAULT.copy().addBeanTypes().addRootType().build(), UrlEncodingParser.DEFAULT),
57  		input("Uon", UonSerializer.DEFAULT.copy().addBeanTypes().addRootType().build(), UonParser.DEFAULT)
58  	};
59  
60  	private static Input input(String label, Serializer serializer, Parser parser) {
61  		return new Input(label, serializer, parser);
62  	}
63  
64  	private static class Input {
65  		ThirdPartyProxy proxy;
66  
67  		Input(String label, Serializer serializer, Parser parser) {
68  			proxy = MockRestClient.create(ThirdPartyProxyResource.class).ignoreErrors().serializer(serializer).parser(parser).partSerializer(UonSerializer.create().addBeanTypes().addRootType().build()).build().getRemote(ThirdPartyProxy.class, null, serializer, parser);
69  		}
70  	}
71  
72  	static Input[] input() {
73  		return INPUT;
74  	}
75  
76  	//-----------------------------------------------------------------------------------------------------------------
77  	// Header tests
78  	//-----------------------------------------------------------------------------------------------------------------
79  
80  	@ParameterizedTest
81  	@MethodSource("input")
82  	void a01_primitiveHeaders(Input input) {
83  		var r = input.proxy.primitiveHeaders(
84  			"foo",
85  			null,
86  			123,
87  			123,
88  			null,
89  			true,
90  			1.0f,
91  			1.0f
92  		);
93  		assertEquals("OK", r);
94  	}
95  
96  	@ParameterizedTest
97  	@MethodSource("input")
98  	void a02_primitiveCollectionHeaders(Input input) {
99  		var r = input.proxy.primitiveCollectionHeaders(
100 			new int[][][]{{{1,2},null},null},
101 			new Integer[][][]{{{1,null},null},null},
102 			new String[][][]{{{"foo",null},null},null},
103 			alist(1,null),
104 			alist(alist(alist(1,null),null),null),
105 			alist(new Integer[][][]{{{1,null},null},null},null),
106 			alist(new int[][][]{{{1,2},null},null},null),
107 			alist("foo","bar",null)
108 		);
109 		assertEquals("OK", r);
110 	}
111 
112 	@ParameterizedTest
113 	@MethodSource("input")
114 	void a03_beanHeaders(Input input) {
115 		var r = input.proxy.beanHeaders(
116 			ABean.get(),
117 			null,
118 			new ABean[][][]{{{ABean.get(),null},null},null},
119 			alist(ABean.get(),null),
120 			alist(new ABean[][][]{{{ABean.get(),null},null},null},null),
121 			map("foo",ABean.get()),
122 			map("foo",alist(ABean.get())),
123 			map("foo",alist(new ABean[][][]{{{ABean.get(),null},null},null},null)),
124 			map(1,alist(ABean.get()))
125 		);
126 		assertEquals("OK", r);
127 	}
128 
129 	@ParameterizedTest
130 	@MethodSource("input")
131 	void a04_typedBeanHeaders(Input input) {
132 		var r = input.proxy.typedBeanHeaders(
133 			TypedBeanImpl.get(),
134 			null,
135 			new TypedBean[][][]{{{TypedBeanImpl.get(),null},null},null},
136 			alist(TypedBeanImpl.get(),null),
137 			alist(new TypedBean[][][]{{{TypedBeanImpl.get(),null},null},null},null),
138 			map("foo",TypedBeanImpl.get()),
139 			map("foo",alist((TypedBean)TypedBeanImpl.get())),
140 			map("foo",alist(new TypedBean[][][]{{{TypedBeanImpl.get(),null},null},null},null)),
141 			map(1,alist((TypedBean)TypedBeanImpl.get()))
142 		);
143 		assertEquals("OK", r);
144 	}
145 
146 	@ParameterizedTest
147 	@MethodSource("input")
148 	void a05_swappedObjectHeaders(Input input) {
149 		var r = input.proxy.swappedObjectHeaders(
150 			new SwappedObject(),
151 			new SwappedObject[][][]{{{new SwappedObject(),null},null},null},
152 			map(new SwappedObject(),new SwappedObject()),
153 			map(new SwappedObject(),new SwappedObject[][][]{{{new SwappedObject(),null},null},null})
154 		);
155 		assertEquals("OK", r);
156 	}
157 
158 	@ParameterizedTest
159 	@MethodSource("input")
160 	void a06_implicitSwappedObjectHeaders(Input input) {
161 		var r = input.proxy.implicitSwappedObjectHeaders(
162 			new ImplicitSwappedObject(),
163 			new ImplicitSwappedObject[][][]{{{new ImplicitSwappedObject(),null},null},null},
164 			map(new ImplicitSwappedObject(),new ImplicitSwappedObject()),
165 			map(new ImplicitSwappedObject(),new ImplicitSwappedObject[][][]{{{new ImplicitSwappedObject(),null},null},null})
166 		);
167 		assertEquals("OK", r);
168 	}
169 
170 	@ParameterizedTest
171 	@MethodSource("input")
172 	void a07_enumHeaders(Input input) {
173 		var r = input.proxy.enumHeaders(
174 			TestEnum.TWO,
175 			null,
176 			new TestEnum[][][]{{{TestEnum.TWO,null},null},null},
177 			alist(TestEnum.TWO,null),
178 			alist(alist(alist(TestEnum.TWO,null),null),null),
179 			alist(new TestEnum[][][]{{{TestEnum.TWO,null},null},null},null),
180 			map(TestEnum.ONE,TestEnum.TWO),
181 			map(TestEnum.ONE,new TestEnum[][][]{{{TestEnum.TWO,null},null},null}),
182 			map(TestEnum.ONE,alist(new TestEnum[][][]{{{TestEnum.TWO,null},null},null},null))
183 		);
184 		assertEquals("OK", r);
185 	}
186 
187 	@ParameterizedTest
188 	@MethodSource("input")
189 	void a08_mapHeader(Input input) {
190 		var r = input.proxy.mapHeader(
191 			map("a","foo","b","","c",null)
192 		);
193 		assertEquals("OK", r);
194 	}
195 
196 	@ParameterizedTest
197 	@MethodSource("input")
198 	void a09_beanHeader(Input input) {
199 		var r = input.proxy.beanHeader(
200 			new NeBean().init()
201 		);
202 		assertEquals("OK", r);
203 	}
204 
205 	@ParameterizedTest
206 	@MethodSource("input")
207 	void a10_headerList(Input input) {
208 		var r = input.proxy.headerList(
209 			headerList("a","foo","b","","c",null)
210 		);
211 		assertEquals("OK", r);
212 	}
213 
214 	//-----------------------------------------------------------------------------------------------------------------
215 	// Query tests
216 	//-----------------------------------------------------------------------------------------------------------------
217 
218 	@ParameterizedTest
219 	@MethodSource("input")
220 	void b01_primitiveQueries(Input input) {
221 		var r = input.proxy.primitiveQueries(
222 			"foo",
223 			null,
224 			123,
225 			123,
226 			null,
227 			true,
228 			1.0f,
229 			1.0f
230 		);
231 		assertEquals("OK", r);
232 	}
233 
234 	@ParameterizedTest
235 	@MethodSource("input")
236 	void b02_primitiveCollectionQueries(Input input) {
237 		var r = input.proxy.primitiveCollectionQueries(
238 			new int[][][]{{{1,2},null},null},
239 			new Integer[][][]{{{1,null},null},null},
240 			new String[][][]{{{"foo",null},null},null},
241 			alist(1,null),
242 			alist(alist(alist(1,null),null),null),
243 			alist(new Integer[][][]{{{1,null},null},null},null),
244 			alist(new int[][][]{{{1,2},null},null},null),
245 			alist("foo","bar",null)
246 		);
247 		assertEquals("OK", r);
248 	}
249 
250 	@ParameterizedTest
251 	@MethodSource("input")
252 	void b03_beanQueries(Input input) {
253 		var r = input.proxy.beanQueries(
254 			ABean.get(),
255 			null,
256 			new ABean[][][]{{{ABean.get(),null},null},null},
257 			alist(ABean.get(),null),
258 			alist(new ABean[][][]{{{ABean.get(),null},null},null},null),
259 			map("foo",ABean.get()),
260 			map("foo",alist(ABean.get())),
261 			map("foo",alist(new ABean[][][]{{{ABean.get(),null},null},null},null)),
262 			map(1,alist(ABean.get()))
263 		);
264 		assertEquals("OK", r);
265 	}
266 
267 
268 	@ParameterizedTest
269 	@MethodSource("input")
270 	void b04_typedBeanQueries(Input input) {
271 		var r = input.proxy.typedBeanQueries(
272 			TypedBeanImpl.get(),
273 			null,
274 			new TypedBean[][][]{{{TypedBeanImpl.get(),null},null},null},
275 			alist(TypedBeanImpl.get(),null),
276 			alist(new TypedBean[][][]{{{TypedBeanImpl.get(),null},null},null},null),
277 			map("foo",TypedBeanImpl.get()),
278 			map("foo",alist((TypedBean)TypedBeanImpl.get())),
279 			map("foo",alist(new TypedBean[][][]{{{TypedBeanImpl.get(),null},null},null},null)),
280 			map(1,alist((TypedBean)TypedBeanImpl.get()))
281 		);
282 		assertEquals("OK", r);
283 	}
284 
285 	@ParameterizedTest
286 	@MethodSource("input")
287 	void b05_swappedObjectQueries(Input input) {
288 		var r = input.proxy.swappedObjectQueries(
289 			new SwappedObject(),
290 			new SwappedObject[][][]{{{new SwappedObject(),null},null},null},
291 			map(new SwappedObject(),new SwappedObject()),
292 			map(new SwappedObject(),new SwappedObject[][][]{{{new SwappedObject(),null},null},null})
293 		);
294 		assertEquals("OK", r);
295 	}
296 
297 	@ParameterizedTest
298 	@MethodSource("input")
299 	void b06_implicitSwappedObjectQueries(Input input) {
300 		var r = input.proxy.implicitSwappedObjectQueries(
301 			new ImplicitSwappedObject(),
302 			new ImplicitSwappedObject[][][]{{{new ImplicitSwappedObject(),null},null},null},
303 			map(new ImplicitSwappedObject(),new ImplicitSwappedObject()),
304 			map(new ImplicitSwappedObject(),new ImplicitSwappedObject[][][]{{{new ImplicitSwappedObject(),null},null},null})
305 		);
306 		assertEquals("OK", r);
307 	}
308 
309 	@ParameterizedTest
310 	@MethodSource("input")
311 	void b07_enumQueries(Input input) {
312 		var r = input.proxy.enumQueries(
313 			TestEnum.TWO,
314 			null,
315 			new TestEnum[][][]{{{TestEnum.TWO,null},null},null},
316 			alist(TestEnum.TWO,null),
317 			alist(alist(alist(TestEnum.TWO,null),null),null),
318 			alist(new TestEnum[][][]{{{TestEnum.TWO,null},null},null},null),
319 			map(TestEnum.ONE,TestEnum.TWO),
320 			map(TestEnum.ONE,new TestEnum[][][]{{{TestEnum.TWO,null},null},null}),
321 			map(TestEnum.ONE,alist(new TestEnum[][][]{{{TestEnum.TWO,null},null},null},null))
322 		);
323 		assertEquals("OK", r);
324 	}
325 
326 	@ParameterizedTest
327 	@MethodSource("input")
328 	void b08_stringQuery1(Input input) {
329 		var r = input.proxy.stringQuery1("a=1&b=foo");
330 		assertEquals("OK", r);
331 	}
332 
333 	@ParameterizedTest
334 	@MethodSource("input")
335 	void b09_stringQuery2(Input input) {
336 		var r = input.proxy.stringQuery2("a=1&b=foo");
337 		assertEquals("OK", r);
338 	}
339 
340 	@ParameterizedTest
341 	@MethodSource("input")
342 	void b10_mapQuery(Input input) {
343 		var r = input.proxy.mapQuery(
344 			map("a",1,"b","foo")
345 		);
346 		assertEquals("OK", r);
347 	}
348 
349 	@ParameterizedTest
350 	@MethodSource("input")
351 	void b11_beanQuery(Input input) {
352 		var r = input.proxy.beanQuery(
353 			new NeBean().init()
354 		);
355 		assertEquals("OK", r);
356 	}
357 
358 	@ParameterizedTest
359 	@MethodSource("input")
360 	void b12_partListQuery(Input input) {
361 		var r = input.proxy.partListQuery(
362 			partList("a","foo","b","","c",null)
363 		);
364 		assertEquals("OK", r);
365 	}
366 
367 	//-----------------------------------------------------------------------------------------------------------------
368 	// FormData tests
369 	//-----------------------------------------------------------------------------------------------------------------
370 
371 	@ParameterizedTest
372 	@MethodSource("input")
373 	void c01_primitiveFormData(Input input) {
374 		var r = input.proxy.primitiveFormData(
375 			"foo",
376 			null,
377 			123,
378 			123,
379 			null,
380 			true,
381 			1.0f,
382 			1.0f
383 		);
384 		assertEquals("OK", r);
385 	}
386 
387 	@ParameterizedTest
388 	@MethodSource("input")
389 	void c02_primitiveCollectionFormData(Input input) {
390 		var r = input.proxy.primitiveCollectionFormData(
391 			new int[][][]{{{1,2},null},null},
392 			new Integer[][][]{{{1,null},null},null},
393 			new String[][][]{{{"foo",null},null},null},
394 			alist(1,null),
395 			alist(alist(alist(1,null),null),null),
396 			alist(new Integer[][][]{{{1,null},null},null},null),
397 			alist(new int[][][]{{{1,2},null},null},null),
398 			alist("foo","bar",null)
399 		);
400 		assertEquals("OK", r);
401 	}
402 
403 	@ParameterizedTest
404 	@MethodSource("input")
405 	void c03_beanFormData(Input input) {
406 		var r = input.proxy.beanFormData(
407 			ABean.get(),
408 			null,
409 			new ABean[][][]{{{ABean.get(),null},null},null},
410 			alist(ABean.get(),null),
411 			alist(new ABean[][][]{{{ABean.get(),null},null},null},null),
412 			map("foo",ABean.get()),
413 			map("foo",alist(ABean.get())),
414 			map("foo",alist(new ABean[][][]{{{ABean.get(),null},null},null},null)),
415 			map(1,alist(ABean.get()))
416 		);
417 		assertEquals("OK", r);
418 	}
419 
420 
421 	@ParameterizedTest
422 	@MethodSource("input")
423 	void c04_typedBeanFormData(Input input) {
424 		var r = input.proxy.typedBeanFormData(
425 			TypedBeanImpl.get(),
426 			null,
427 			new TypedBean[][][]{{{TypedBeanImpl.get(),null},null},null},
428 			alist(TypedBeanImpl.get(),null),
429 			alist(new TypedBean[][][]{{{TypedBeanImpl.get(),null},null},null},null),
430 			map("foo",TypedBeanImpl.get()),
431 			map("foo",alist((TypedBean)TypedBeanImpl.get())),
432 			map("foo",alist(new TypedBean[][][]{{{TypedBeanImpl.get(),null},null},null},null)),
433 			map(1,alist((TypedBean)TypedBeanImpl.get()))
434 		);
435 		assertEquals("OK", r);
436 	}
437 
438 	@ParameterizedTest
439 	@MethodSource("input")
440 	void c05_swappedObjectFormData(Input input) {
441 		var r = input.proxy.swappedObjectFormData(
442 			new SwappedObject(),
443 			new SwappedObject[][][]{{{new SwappedObject(),null},null},null},
444 			map(new SwappedObject(),new SwappedObject()),
445 			map(new SwappedObject(),new SwappedObject[][][]{{{new SwappedObject(),null},null},null})
446 		);
447 		assertEquals("OK", r);
448 	}
449 
450 	@ParameterizedTest
451 	@MethodSource("input")
452 	void c06_implicitSwappedObjectFormData(Input input) {
453 		var r = input.proxy.implicitSwappedObjectFormData(
454 			new ImplicitSwappedObject(),
455 			new ImplicitSwappedObject[][][]{{{new ImplicitSwappedObject(),null},null},null},
456 			map(new ImplicitSwappedObject(),new ImplicitSwappedObject()),
457 			map(new ImplicitSwappedObject(),new ImplicitSwappedObject[][][]{{{new ImplicitSwappedObject(),null},null},null})
458 		);
459 		assertEquals("OK", r);
460 	}
461 
462 	@ParameterizedTest
463 	@MethodSource("input")
464 	void c07_enumFormData(Input input) {
465 		var r = input.proxy.enumFormData(
466 			TestEnum.TWO,
467 			null,
468 			new TestEnum[][][]{{{TestEnum.TWO,null},null},null},
469 			alist(TestEnum.TWO,null),
470 			alist(alist(alist(TestEnum.TWO,null),null),null),
471 			alist(new TestEnum[][][]{{{TestEnum.TWO,null},null},null},null),
472 			map(TestEnum.ONE,TestEnum.TWO),
473 			map(TestEnum.ONE,new TestEnum[][][]{{{TestEnum.TWO,null},null},null}),
474 			map(TestEnum.ONE,alist(new TestEnum[][][]{{{TestEnum.TWO,null},null},null},null))
475 		);
476 		assertEquals("OK", r);
477 	}
478 
479 	@ParameterizedTest
480 	@MethodSource("input")
481 	void c08_mapFormData(Input input) {
482 		var r = input.proxy.mapFormData(
483 			map("a","foo","b","","c",null)
484 		);
485 		assertEquals("OK", r);
486 	}
487 
488 	@ParameterizedTest
489 	@MethodSource("input")
490 	void c09_beanFormData(Input input) {
491 		var r = input.proxy.beanFormData(
492 			new NeBean().init()
493 		);
494 		assertEquals("OK", r);
495 	}
496 
497 	@ParameterizedTest
498 	@MethodSource("input")
499 	void c10_partListFormData(Input input) {
500 		var r = input.proxy.partListFormData(
501 			partList("a","foo","b","","c",null)
502 		);
503 		assertEquals("OK", r);
504 	}
505 
506 	//-----------------------------------------------------------------------------------------------------------------
507 	// Test return types.
508 	//-----------------------------------------------------------------------------------------------------------------
509 
510 	// Various primitives
511 	@ParameterizedTest
512 	@MethodSource("input")
513 	void da01_returnVoid(Input input) {
514 		assertDoesNotThrow(()->input.proxy.returnVoid());
515 	}
516 
517 	@ParameterizedTest
518 	@MethodSource("input")
519 	void da02_returnInteger(Input input) {
520 		assertEquals((Integer)1, input.proxy.returnInteger());
521 	}
522 
523 	@ParameterizedTest
524 	@MethodSource("input")
525 	void da03_returnInt(Input input) {
526 		assertEquals(1, input.proxy.returnInt());
527 	}
528 
529 	@ParameterizedTest
530 	@MethodSource("input")
531 	void da04_returnBoolean(Input input) {
532 		assertEquals(true, input.proxy.returnBoolean());
533 	}
534 
535 	@ParameterizedTest
536 	@MethodSource("input")
537 	void da05_returnFloat(Input input) {
538 		assertEquals(1f, input.proxy.returnFloat(), 0.1f);
539 	}
540 
541 	@ParameterizedTest
542 	@MethodSource("input")
543 	void da06_returnFloatObject(Input input) {
544 		assertEquals(1f, input.proxy.returnFloatObject(), 0.1f);
545 	}
546 
547 	@ParameterizedTest
548 	@MethodSource("input")
549 	void da07_returnString(Input input) {
550 		assertEquals("foobar", input.proxy.returnString());
551 	}
552 
553 	@ParameterizedTest
554 	@MethodSource("input")
555 	void da08_returnNullString(Input input) {
556 		assertNull(input.proxy.returnNullString());
557 	}
558 
559 	@ParameterizedTest
560 	@MethodSource("input")
561 	void da09_returnInt3dArray(Input input) {
562 		assertList(input.proxy.returnInt3dArray(), "[[1,2],<null>]",null);
563 	}
564 
565 	@ParameterizedTest
566 	@MethodSource("input")
567 	void da10_returnInteger3dArray(Input input) {
568 		assertList(input.proxy.returnInteger3dArray(), "[[1,<null>],<null>]",null);
569 	}
570 
571 	@ParameterizedTest
572 	@MethodSource("input")
573 	void da11_returnString3dArray(Input input) {
574 		assertList(input.proxy.returnString3dArray(), "[[foo,bar,<null>],<null>]",null);
575 	}
576 
577 	@ParameterizedTest
578 	@MethodSource("input")
579 	void da12_returnIntegerList(Input input) {
580 		var x = input.proxy.returnIntegerList();
581 		assertList(x, 1, null);
582 		assertInstanceOf(Integer.class, x.get(0));
583 	}
584 
585 	@ParameterizedTest
586 	@MethodSource("input")
587 	void da13_returnInteger3dList(Input input) {
588 		var x = input.proxy.returnInteger3dList();
589 		assertList(x, "[[1,<null>],<null>]",null);
590 		assertInstanceOf(Integer.class, x.get(0).get(0).get(0));
591 	}
592 
593 	@ParameterizedTest
594 	@MethodSource("input")
595 	void da14_returnInteger1d3dList(Input input) {
596 		var x = input.proxy.returnInteger1d3dList();
597 		assertList(x, "[[[1,<null>],<null>],<null>]",null);
598 		assertInstanceOf(Integer.class, x.get(0)[0][0][0]);
599 	}
600 
601 	@ParameterizedTest
602 	@MethodSource("input")
603 	void da15_returnInt1d3dList(Input input) {
604 		var x = input.proxy.returnInt1d3dList();
605 		assertList(x, "[[[1,2],<null>],<null>]",null);
606 		assertInstanceOf(int[][][].class, x.get(0));
607 	}
608 
609 	@ParameterizedTest
610 	@MethodSource("input")
611 	void da16_returnStringList(Input input) {
612 		assertList(input.proxy.returnStringList(), "foo", "bar", null);
613 	}
614 
615 	// Beans
616 
617 	@ParameterizedTest
618 	@MethodSource("input")
619 	void db01_returnBean(Input input) {
620 		var x = input.proxy.returnBean();
621 		assertBean(x, "a,b", "1,foo");
622 		assertInstanceOf(ABean.class, x);
623 	}
624 
625 	@ParameterizedTest
626 	@MethodSource("input")
627 	void db02_returnBean3dArray(Input input) {
628 		var x = input.proxy.returnBean3dArray();
629 		assertList(x, "[[{a:1,b:'foo'},<null>],<null>]",null);
630 		assertInstanceOf(ABean.class, x[0][0][0]);
631 	}
632 
633 	@ParameterizedTest
634 	@MethodSource("input")
635 	void db03_returnBeanList(Input input) {
636 		var x = input.proxy.returnBeanList();
637 		assertList(x, "{a:1,b:'foo'}");
638 		assertInstanceOf(ABean.class, x.get(0));
639 	}
640 
641 	@ParameterizedTest
642 	@MethodSource("input")
643 	void db04_returnBean1d3dList(Input input) {
644 		var x = input.proxy.returnBean1d3dList();
645 		assertList(x, "[[[{a:1,b:'foo'},<null>],<null>],<null>]",null);
646 		assertInstanceOf(ABean.class, x.get(0)[0][0][0]);
647 	}
648 
649 	@ParameterizedTest
650 	@MethodSource("input")
651 	void db05_returnBeanMap(Input input) {
652 		var x = input.proxy.returnBeanMap();
653 		assertMap(x, "foo", "{a:1,b:'foo'}");
654 		assertInstanceOf(ABean.class, x.get("foo"));
655 	}
656 
657 	@ParameterizedTest
658 	@MethodSource("input")
659 	void db06_returnBeanListMap(Input input) {
660 		var x = input.proxy.returnBeanListMap();
661 		assertMap(x, "foo", "[{a:1,b:'foo'}]");
662 		assertInstanceOf(ABean.class, x.get("foo").get(0));
663 	}
664 
665 	@ParameterizedTest
666 	@MethodSource("input")
667 	void db07_returnBean1d3dListMap(Input input) {
668 		var x = input.proxy.returnBean1d3dListMap();
669 		assertMap(x, "foo", "[[[[{a:1,b:'foo'},<null>],<null>],<null>],<null>]");
670 		assertInstanceOf(ABean.class, x.get("foo").get(0)[0][0][0]);
671 	}
672 
673 	@ParameterizedTest
674 	@MethodSource("input")
675 	void db08_returnBeanListMapIntegerKeys(Input input) {
676 		// Note: JsonSerializer serializes key as string.
677 		var x = input.proxy.returnBeanListMapIntegerKeys();
678 		assertList(x, "1=[{a:1,b:'foo'}]");
679 		assertInstanceOf(Integer.class, x.keySet().iterator().next());
680 	}
681 
682 	// Typed beans
683 
684 	@ParameterizedTest
685 	@MethodSource("input")
686 	void dc01_returnTypedBean(Input input) {
687 		var x = input.proxy.returnTypedBean();
688 		assertBean(x, "a,b", "1,foo");
689 		assertInstanceOf(TypedBeanImpl.class, x);
690 	}
691 
692 	@ParameterizedTest
693 	@MethodSource("input")
694 	void dc02_returnTypedBean3dArray(Input input) {
695 		var x = input.proxy.returnTypedBean3dArray();
696 		assertList(x, "[[a:1;b:foo,<null>],<null>]",null);
697 		assertInstanceOf(TypedBeanImpl.class, x[0][0][0]);
698 	}
699 
700 	@ParameterizedTest
701 	@MethodSource("input")
702 	void dc03_returnTypedBeanList(Input input) {
703 		var x = input.proxy.returnTypedBeanList();
704 		assertList(x, "a:1;b:foo");
705 		assertInstanceOf(TypedBeanImpl.class, x.get(0));
706 	}
707 
708 	@ParameterizedTest
709 	@MethodSource("input")
710 	void dc04_returnTypedBean1d3dList(Input input) {
711 		var x = input.proxy.returnTypedBean1d3dList();
712 		assertList(x, "[[[a:1;b:foo,<null>],<null>],<null>]",null);
713 		assertInstanceOf(TypedBeanImpl.class, x.get(0)[0][0][0]);
714 	}
715 
716 	@ParameterizedTest
717 	@MethodSource("input")
718 	void dc05_returnTypedBeanMap(Input input) {
719 		var x = input.proxy.returnTypedBeanMap();
720 		assertMap(x, "foo", "a:1;b:foo");
721 		assertInstanceOf(TypedBeanImpl.class, x.get("foo"));
722 	}
723 
724 	@ParameterizedTest
725 	@MethodSource("input")
726 	void dc06_returnTypedBeanListMap(Input input) {
727 		var x = input.proxy.returnTypedBeanListMap();
728 		assertMap(x, "foo", "[a:1;b:foo]");
729 		assertInstanceOf(TypedBeanImpl.class, x.get("foo").get(0));
730 	}
731 
732 	@ParameterizedTest
733 	@MethodSource("input")
734 	void dc07_returnTypedBean1d3dListMap(Input input) {
735 		var x = input.proxy.returnTypedBean1d3dListMap();
736 		assertMap(x, "foo", "[[[[a:1;b:foo,<null>],<null>],<null>],<null>]");
737 		assertInstanceOf(TypedBeanImpl.class, x.get("foo").get(0)[0][0][0]);
738 	}
739 
740 	@ParameterizedTest
741 	@MethodSource("input")
742 	void dc08_returnTypedBeanListMapIntegerKeys(Input input) {
743 		// Note: JsonSerializer serializes key as string.
744 		var x = input.proxy.returnTypedBeanListMapIntegerKeys();
745 		assertJson("{'1':[{a:1,b:'foo'}]}", x);
746 		assertInstanceOf(TypedBeanImpl.class, x.get(1).get(0));
747 	}
748 
749 	// Swapped POJOs
750 
751 	@ParameterizedTest
752 	@MethodSource("input")
753 	void dd01_returnSwappedObject(Input input) {
754 		var x = input.proxy.returnSwappedObject();
755 		assertJson("'"+SWAP+"'", x);
756 		assertTrue(x.wasUnswapped);
757 	}
758 
759 	@ParameterizedTest
760 	@MethodSource("input")
761 	void dd02_returnSwappedObject3dArray(Input input) {
762 		var x = input.proxy.returnSwappedObject3dArray();
763 		assertJson("[[['"+SWAP+"',null],null],null]", x);
764 		assertTrue(x[0][0][0].wasUnswapped);
765 	}
766 
767 	@ParameterizedTest
768 	@MethodSource("input")
769 	void dd03_returnSwappedObjectMap(Input input) {
770 		var x = input.proxy.returnSwappedObjectMap();
771 		assertJson("{'"+SWAP+"':'"+SWAP+"'}", x);
772 		var e = x.entrySet().iterator().next();
773 		assertTrue(e.getKey().wasUnswapped);
774 		assertTrue(e.getValue().wasUnswapped);
775 	}
776 
777 	@ParameterizedTest
778 	@MethodSource("input")
779 	void dd04_returnSwappedObject3dMap(Input input) {
780 		var x = input.proxy.returnSwappedObject3dMap();
781 		assertJson("{'"+SWAP+"':[[['"+SWAP+"',null],null],null]}", x);
782 		var e = x.entrySet().iterator().next();
783 		assertTrue(e.getKey().wasUnswapped);
784 		assertTrue(e.getValue()[0][0][0].wasUnswapped);
785 	}
786 
787 	// Implicit swapped POJOs
788 
789 	@ParameterizedTest
790 	@MethodSource("input")
791 	void de01_returnImplicitSwappedObject(Input input) {
792 		var x = input.proxy.returnImplicitSwappedObject();
793 		assertJson("'"+SWAP+"'", x);
794 		assertTrue(x.wasUnswapped);
795 	}
796 
797 	@ParameterizedTest
798 	@MethodSource("input")
799 	void de02_returnImplicitSwappedObject3dArray(Input input) {
800 		var x = input.proxy.returnImplicitSwappedObject3dArray();
801 		assertJson("[[['"+SWAP+"',null],null],null]", x);
802 		assertTrue(x[0][0][0].wasUnswapped);
803 	}
804 
805 	@ParameterizedTest
806 	@MethodSource("input")
807 	void de03_returnImplicitSwappedObjectMap(Input input) {
808 		var x = input.proxy.returnImplicitSwappedObjectMap();
809 		assertJson("{'"+SWAP+"':'"+SWAP+"'}", x);
810 		var e = x.entrySet().iterator().next();
811 		assertTrue(e.getKey().wasUnswapped);
812 		assertTrue(e.getValue().wasUnswapped);
813 	}
814 
815 	@ParameterizedTest
816 	@MethodSource("input")
817 	void de04_returnImplicitSwappedObject3dMap(Input input) {
818 		var x = input.proxy.returnImplicitSwappedObject3dMap();
819 		assertJson("{'"+SWAP+"':[[['"+SWAP+"',null],null],null]}", x);
820 		var e = x.entrySet().iterator().next();
821 		assertTrue(e.getKey().wasUnswapped);
822 		assertTrue(e.getValue()[0][0][0].wasUnswapped);
823 	}
824 
825 	// Enums
826 
827 	@ParameterizedTest
828 	@MethodSource("input")
829 	void df01_returnEnum(Input input) {
830 		var x = input.proxy.returnEnum();
831 		assertEquals(TestEnum.TWO, x);
832 	}
833 
834 	@ParameterizedTest
835 	@MethodSource("input")
836 	void df02_returnEnum3d(Input input) {
837 		var x = input.proxy.returnEnum3d();
838 		assertList(x, "[[TWO,<null>],<null>]",null);
839 		assertInstanceOf(TestEnum.class, x[0][0][0]);
840 	}
841 
842 	@ParameterizedTest
843 	@MethodSource("input")
844 	void df03_returnEnumList(Input input) {
845 		var x = input.proxy.returnEnumList();
846 		assertList(x, "TWO", null);
847 		assertInstanceOf(TestEnum.class, x.get(0));
848 	}
849 
850 	@ParameterizedTest
851 	@MethodSource("input")
852 	void df04_returnEnum3dList(Input input) {
853 		var x = input.proxy.returnEnum3dList();
854 		assertList(x, "[[TWO,<null>],<null>]", null);
855 		assertInstanceOf(TestEnum.class, x.get(0).get(0).get(0));
856 	}
857 
858 	@ParameterizedTest
859 	@MethodSource("input")
860 	void df05_returnEnum1d3dList(Input input) {
861 		var x = input.proxy.returnEnum1d3dList();
862 		assertList(x, "[[[TWO,<null>],<null>],<null>]", null);
863 		assertInstanceOf(TestEnum[][][].class, x.get(0));
864 	}
865 
866 	@ParameterizedTest
867 	@MethodSource("input")
868 	void df06_returnEnumMap(Input input) {
869 		var x = input.proxy.returnEnumMap();
870 		assertJson("{ONE:'TWO'}", x);
871 		var e = x.entrySet().iterator().next();
872 		assertInstanceOf(TestEnum.class, e.getKey());
873 		assertInstanceOf(TestEnum.class, e.getValue());
874 	}
875 
876 	@ParameterizedTest
877 	@MethodSource("input")
878 	void df07_returnEnum3dArrayMap(Input input) {
879 		var x = input.proxy.returnEnum3dArrayMap();
880 		assertJson("{ONE:[[['TWO',null],null],null]}", x);
881 		var e = x.entrySet().iterator().next();
882 		assertInstanceOf(TestEnum.class, e.getKey());
883 		assertInstanceOf(TestEnum[][][].class, e.getValue());
884 	}
885 
886 	@ParameterizedTest
887 	@MethodSource("input")
888 	void df08_returnEnum1d3dListMap(Input input) {
889 		var x = input.proxy.returnEnum1d3dListMap();
890 		assertJson("{ONE:[[[['TWO',null],null],null],null]}", x);
891 		assertInstanceOf(TestEnum[][][].class, x.get(TestEnum.ONE).get(0));
892 	}
893 
894 	//-----------------------------------------------------------------------------------------------------------------
895 	// Test Body
896 	//-----------------------------------------------------------------------------------------------------------------
897 
898 	// Various primitives
899 
900 	@ParameterizedTest
901 	@MethodSource("input")
902 	void ea01_setInt(Input input) {
903 		assertDoesNotThrow(()->input.proxy.setInt(1));
904 	}
905 
906 	@ParameterizedTest
907 	@MethodSource("input")
908 	void ea02_setWrongInt(Input input) {
909 		assertThrowsWithMessage(AssertionFailedError.class, "expected: <1> but was: <2>", ()->input.proxy.setInt(2));
910 	}
911 
912 	@ParameterizedTest
913 	@MethodSource("input")
914 	void ea03_setInteger(Input input) {
915 		assertDoesNotThrow(()->input.proxy.setInteger(1));
916 	}
917 
918 	@ParameterizedTest
919 	@MethodSource("input")
920 	void ea04_setBoolean(Input input) {
921 		assertDoesNotThrow(()->input.proxy.setBoolean(true));
922 	}
923 
924 	@ParameterizedTest
925 	@MethodSource("input")
926 	void ea05_setFloat(Input input) {
927 		assertDoesNotThrow(()->input.proxy.setFloat(1f));
928 	}
929 
930 	@ParameterizedTest
931 	@MethodSource("input")
932 	void ea06_setFloatObject(Input input) {
933 		assertDoesNotThrow(()->input.proxy.setFloatObject(1f));
934 	}
935 
936 	@ParameterizedTest
937 	@MethodSource("input")
938 	void ea07_setString(Input input) {
939 		assertDoesNotThrow(()->input.proxy.setString("foo"));
940 	}
941 
942 	@ParameterizedTest
943 	@MethodSource("input")
944 	void ea08_setNullString(Input input) {
945 		assertDoesNotThrow(()->input.proxy.setNullString(null));
946 	}
947 
948 	@ParameterizedTest
949 	@MethodSource("input")
950 	void ea09_setNullStringBad(Input input) {
951 		assertThrowsWithMessage(AssertionFailedError.class, "expected: <null> but was: <foo>", ()->input.proxy.setNullString("foo"));
952 	}
953 
954 	@ParameterizedTest
955 	@MethodSource("input")
956 	void ea10_setInt3dArray(Input input) {
957 		assertDoesNotThrow(()->input.proxy.setInt3dArray(new int[][][]{{{1},null},null}, 1));
958 	}
959 
960 	@ParameterizedTest
961 	@MethodSource("input")
962 	void ea11_setInteger3dArray(Input input) {
963 		assertDoesNotThrow(()->input.proxy.setInteger3dArray(new Integer[][][]{{{1,null},null},null}));
964 	}
965 
966 	@ParameterizedTest
967 	@MethodSource("input")
968 	void ea12_setString3dArray(Input input) {
969 		assertDoesNotThrow(()->input.proxy.setString3dArray(new String[][][]{{{"foo",null},null},null}));
970 	}
971 
972 	@ParameterizedTest
973 	@MethodSource("input")
974 	void ea13_setIntegerList(Input input) {
975 		assertDoesNotThrow(()->input.proxy.setIntegerList(alist(1,null)));
976 	}
977 
978 	@ParameterizedTest
979 	@MethodSource("input")
980 	void ea14_setInteger3dList(Input input) {
981 		assertDoesNotThrow(()->input.proxy.setInteger3dList(alist(alist(alist(1,null),null),null)));
982 	}
983 
984 	@ParameterizedTest
985 	@MethodSource("input")
986 	void ea15_setInteger1d3dList(Input input) {
987 		assertDoesNotThrow(()->input.proxy.setInteger1d3dList(alist(new Integer[][][]{{{1,null},null},null},null)));
988 	}
989 
990 	@ParameterizedTest
991 	@MethodSource("input")
992 	void ea16_setInt1d3dList(Input input) {
993 		assertDoesNotThrow(()->input.proxy.setInt1d3dList(alist(new int[][][]{{{1,2},null},null},null)));
994 	}
995 
996 	@ParameterizedTest
997 	@MethodSource("input")
998 	void ea17_setStringList(Input input) {
999 		assertDoesNotThrow(()->input.proxy.setStringList(alist("foo","bar",null)));
1000 	}
1001 
1002 	// Beans
1003 	@ParameterizedTest
1004 	@MethodSource("input")
1005 	void eb01_setBean(Input input) {
1006 		assertDoesNotThrow(()->input.proxy.setBean(ABean.get()));
1007 	}
1008 
1009 	@ParameterizedTest
1010 	@MethodSource("input")
1011 	void eb02_setBean3dArray(Input input) {
1012 		assertDoesNotThrow(()->input.proxy.setBean3dArray(new ABean[][][]{{{ABean.get(),null},null},null}));
1013 	}
1014 
1015 	@ParameterizedTest
1016 	@MethodSource("input")
1017 	void eb03_setBeanList(Input input) {
1018 		assertDoesNotThrow(()->input.proxy.setBeanList(alist(ABean.get())));
1019 	}
1020 
1021 	@ParameterizedTest
1022 	@MethodSource("input")
1023 	void eb04_setBean1d3dList(Input input) {
1024 		assertDoesNotThrow(()->input.proxy.setBean1d3dList(alist(new ABean[][][]{{{ABean.get(),null},null},null},null)));
1025 	}
1026 
1027 	@ParameterizedTest
1028 	@MethodSource("input")
1029 	void eb05_setBeanMap(Input input) {
1030 		assertDoesNotThrow(()->input.proxy.setBeanMap(map("foo",ABean.get())));
1031 	}
1032 
1033 	@ParameterizedTest
1034 	@MethodSource("input")
1035 	void eb06_setBeanListMap(Input input) {
1036 		assertDoesNotThrow(()->input.proxy.setBeanListMap(map("foo",alist(ABean.get()))));
1037 	}
1038 
1039 	@ParameterizedTest
1040 	@MethodSource("input")
1041 	void eb07_setBean1d3dListMap(Input input) {
1042 		assertDoesNotThrow(()->input.proxy.setBean1d3dListMap(map("foo",alist(new ABean[][][]{{{ABean.get(),null},null},null},null))));
1043 	}
1044 
1045 	@ParameterizedTest
1046 	@MethodSource("input")
1047 	void eb08_setBeanListMapIntegerKeys(Input input) {
1048 		assertDoesNotThrow(()->input.proxy.setBeanListMapIntegerKeys(map(1,alist(ABean.get()))));
1049 	}
1050 
1051 	// Typed beans
1052 
1053 	@ParameterizedTest
1054 	@MethodSource("input")
1055 	void ec01_setTypedBean(Input input) {
1056 		assertDoesNotThrow(()->input.proxy.setTypedBean(TypedBeanImpl.get()));
1057 	}
1058 
1059 	@ParameterizedTest
1060 	@MethodSource("input")
1061 	void ec02_setTypedBean3dArray(Input input) {
1062 		assertDoesNotThrow(()->input.proxy.setTypedBean3dArray(new TypedBean[][][]{{{TypedBeanImpl.get(),null},null},null}));
1063 	}
1064 
1065 	@ParameterizedTest
1066 	@MethodSource("input")
1067 	void ec03_setTypedBeanList(Input input) {
1068 		assertDoesNotThrow(()->input.proxy.setTypedBeanList(alist((TypedBean)TypedBeanImpl.get())));
1069 	}
1070 
1071 	@ParameterizedTest
1072 	@MethodSource("input")
1073 	void ec04_setTypedBean1d3dList(Input input) {
1074 		assertDoesNotThrow(()->input.proxy.setTypedBean1d3dList(alist(new TypedBean[][][]{{{TypedBeanImpl.get(),null},null},null},null)));
1075 	}
1076 
1077 	@ParameterizedTest
1078 	@MethodSource("input")
1079 	void ec05_setTypedBeanMap(Input input) {
1080 		assertDoesNotThrow(()->input.proxy.setTypedBeanMap(map("foo",TypedBeanImpl.get())));
1081 	}
1082 
1083 	@ParameterizedTest
1084 	@MethodSource("input")
1085 	void ec06_setTypedBeanListMap(Input input) {
1086 		assertDoesNotThrow(()->input.proxy.setTypedBeanListMap(map("foo",alist((TypedBean)TypedBeanImpl.get()))));
1087 	}
1088 
1089 	@ParameterizedTest
1090 	@MethodSource("input")
1091 	void ec07_setTypedBean1d3dListMap(Input input) {
1092 		assertDoesNotThrow(()->input.proxy.setTypedBean1d3dListMap(map("foo",alist(new TypedBean[][][]{{{TypedBeanImpl.get(),null},null},null},null))));
1093 	}
1094 
1095 	@ParameterizedTest
1096 	@MethodSource("input")
1097 	void ec08_setTypedBeanListMapIntegerKeys(Input input) {
1098 		assertDoesNotThrow(()->input.proxy.setTypedBeanListMapIntegerKeys(map(1,alist((TypedBean)TypedBeanImpl.get()))));
1099 	}
1100 
1101 	// Swapped POJOs
1102 
1103 	@ParameterizedTest
1104 	@MethodSource("input")
1105 	void ed01_setSwappedObject(Input input) {
1106 		assertDoesNotThrow(()->input.proxy.setSwappedObject(new SwappedObject()));
1107 	}
1108 
1109 	@ParameterizedTest
1110 	@MethodSource("input")
1111 	void ed02_setSwappedObject3dArray(Input input) {
1112 		assertDoesNotThrow(()->input.proxy.setSwappedObject3dArray(new SwappedObject[][][]{{{new SwappedObject(),null},null},null}));
1113 	}
1114 
1115 	@ParameterizedTest
1116 	@MethodSource("input")
1117 	void ed03_setSwappedObjectMap(Input input) {
1118 		assertDoesNotThrow(()->input.proxy.setSwappedObjectMap(map(new SwappedObject(),new SwappedObject())));
1119 	}
1120 
1121 	@ParameterizedTest
1122 	@MethodSource("input")
1123 	void ed04_setSwappedObject3dMap(Input input) {
1124 		assertDoesNotThrow(()->input.proxy.setSwappedObject3dMap(map(new SwappedObject(),new SwappedObject[][][]{{{new SwappedObject(),null},null},null})));
1125 	}
1126 
1127 	// Implicit swapped POJOs
1128 	@ParameterizedTest
1129 	@MethodSource("input")
1130 	void ee01_setImplicitSwappedObject(Input input) {
1131 		assertDoesNotThrow(()->input.proxy.setImplicitSwappedObject(new ImplicitSwappedObject()));
1132 	}
1133 
1134 	@ParameterizedTest
1135 	@MethodSource("input")
1136 	void ee02_setImplicitSwappedObject3dArray(Input input) {
1137 		assertDoesNotThrow(()->input.proxy.setImplicitSwappedObject3dArray(new ImplicitSwappedObject[][][]{{{new ImplicitSwappedObject(),null},null},null}));
1138 	}
1139 
1140 	@ParameterizedTest
1141 	@MethodSource("input")
1142 	void ee03_setImplicitSwappedObjectMap(Input input) {
1143 		assertDoesNotThrow(()->input.proxy.setImplicitSwappedObjectMap(map(new ImplicitSwappedObject(),new ImplicitSwappedObject())));
1144 	}
1145 
1146 	@ParameterizedTest
1147 	@MethodSource("input")
1148 	void ee04_setImplicitSwappedObject3dMap(Input input) {
1149 		assertDoesNotThrow(()->input.proxy.setImplicitSwappedObject3dMap(map(new ImplicitSwappedObject(),new ImplicitSwappedObject[][][]{{{new ImplicitSwappedObject(),null},null},null})));
1150 	}
1151 
1152 	// Enums
1153 
1154 	@ParameterizedTest
1155 	@MethodSource("input")
1156 	void ef01_setEnum(Input input) {
1157 		assertDoesNotThrow(()->input.proxy.setEnum(TestEnum.TWO));
1158 	}
1159 
1160 	@ParameterizedTest
1161 	@MethodSource("input")
1162 	void ef02_setEnum3d(Input input) {
1163 		assertDoesNotThrow(()->input.proxy.setEnum3d(new TestEnum[][][]{{{TestEnum.TWO,null},null},null}));
1164 	}
1165 
1166 	@ParameterizedTest
1167 	@MethodSource("input")
1168 	void ef03_setEnumList(Input input) {
1169 		assertDoesNotThrow(()->input.proxy.setEnumList(alist(TestEnum.TWO,null)));
1170 	}
1171 
1172 	@ParameterizedTest
1173 	@MethodSource("input")
1174 	void ef04_setEnum3dList(Input input) {
1175 		assertDoesNotThrow(()->input.proxy.setEnum3dList(alist(alist(alist(TestEnum.TWO,null),null),null)));
1176 	}
1177 
1178 	@ParameterizedTest
1179 	@MethodSource("input")
1180 	void ef05_setEnum1d3dList(Input input) {
1181 		assertDoesNotThrow(()->input.proxy.setEnum1d3dList(alist(new TestEnum[][][]{{{TestEnum.TWO,null},null},null},null)));
1182 	}
1183 
1184 	@ParameterizedTest
1185 	@MethodSource("input")
1186 	void ef06_setEnumMap(Input input) {
1187 		assertDoesNotThrow(()->input.proxy.setEnumMap(map(TestEnum.ONE,TestEnum.TWO)));
1188 	}
1189 
1190 	@ParameterizedTest
1191 	@MethodSource("input")
1192 	void ef07_setEnum3dArrayMap(Input input) {
1193 		assertDoesNotThrow(()->input.proxy.setEnum3dArrayMap(map(TestEnum.ONE,new TestEnum[][][]{{{TestEnum.TWO,null},null},null})));
1194 	}
1195 
1196 	@ParameterizedTest
1197 	@MethodSource("input")
1198 	void ef08_setEnum1d3dListMap(Input input) {
1199 		assertDoesNotThrow(()->input.proxy.setEnum1d3dListMap(map(TestEnum.ONE,alist(new TestEnum[][][]{{{TestEnum.TWO,null},null},null},null))));
1200 	}
1201 
1202 	//-----------------------------------------------------------------------------------------------------------------
1203 	// Path variables
1204 	//-----------------------------------------------------------------------------------------------------------------
1205 
1206 	@ParameterizedTest
1207 	@MethodSource("input")
1208 	void f01_pathVars1(Input input) {
1209 		var r = input.proxy.pathVars1(1, "foo");
1210 		assertEquals("OK", r);
1211 	}
1212 
1213 	@ParameterizedTest
1214 	@MethodSource("input")
1215 	void f02_pathVars2(Input input) {
1216 		var r = input.proxy.pathVars2(
1217 			map("a",1,"b","foo")
1218 		);
1219 		assertEquals("OK", r);
1220 	}
1221 
1222 	@ParameterizedTest
1223 	@MethodSource("input")
1224 	void f03_pathVars3(Input input) {
1225 		var r = input.proxy.pathVars3(
1226 			ABean.get()
1227 		);
1228 		assertEquals("OK", r);
1229 	}
1230 
1231 	//-----------------------------------------------------------------------------------------------------------------
1232 	// @Request tests - Path
1233 	//-----------------------------------------------------------------------------------------------------------------
1234 
1235 	@ParameterizedTest
1236 	@MethodSource("input")
1237 	void ga01_reqBeanPath1(Input input) {
1238 		var r = input.proxy.reqBeanPath1(
1239 			new ThirdPartyProxy.ReqBeanPath1() {
1240 						@Override public int getA() { return 1; }
1241 						@Override public String getB() { return "foo"; }
1242 			}
1243 		);
1244 		assertEquals("OK", r);
1245 	}
1246 
1247 	@ParameterizedTest
1248 	@MethodSource("input")
1249 	void ga01_reqBeanPath1a(Input input) {
1250 		var r = input.proxy.reqBeanPath1(
1251 			new ThirdPartyProxy.ReqBeanPath1Impl()
1252 		);
1253 		assertEquals("OK", r);
1254 	}
1255 
1256 	@ParameterizedTest
1257 	@MethodSource("input")
1258 	void ga02_reqBeanPath2(Input input) {
1259 		var r = input.proxy.reqBeanPath2(
1260 			new ThirdPartyProxy.ReqBeanPath2()
1261 		);
1262 		assertEquals("OK", r);
1263 	}
1264 
1265 	@ParameterizedTest
1266 	@MethodSource("input")
1267 	void ga03_reqBeanPath3(Input input) {
1268 		var r = input.proxy.reqBeanPath3(
1269 			new ThirdPartyProxy.ReqBeanPath3() {
1270 				@Override public int getX() { return 1; }
1271 				@Override public String getY() { return "foo"; }
1272 			}
1273 		);
1274 		assertEquals("OK", r);
1275 	}
1276 
1277 	@ParameterizedTest
1278 	@MethodSource("input")
1279 	void ga06_reqBeanPath6(Input input) {
1280 		var r = input.proxy.reqBeanPath6(() -> map("a", 1, "b", "foo"));
1281 		assertEquals("OK", r);
1282 	}
1283 
1284 	@ParameterizedTest
1285 	@MethodSource("input")
1286 	void ga07_reqBeanPath7(Input input) {
1287 		var r = input.proxy.reqBeanPath7(ABean::get);
1288 		assertEquals("OK", r);
1289 	}
1290 
1291 	//-----------------------------------------------------------------------------------------------------------------
1292 	// @Request tests - Query
1293 	//-----------------------------------------------------------------------------------------------------------------
1294 
1295 	@ParameterizedTest
1296 	@MethodSource("input")
1297 	void gb01_reqBeanQuery1(Input input) {
1298 		var r = input.proxy.reqBeanQuery1(
1299 			new ThirdPartyProxy.ReqBeanQuery1() {
1300 				@Override public int getA() { return 1; }
1301 				@Override public String getB() { return "foo"; }
1302 			}
1303 		);
1304 		assertEquals("OK", r);
1305 	}
1306 
1307 	@ParameterizedTest
1308 	@MethodSource("input")
1309 	void gb01_reqBeanQuery1a(Input input) {
1310 		var r = input.proxy.reqBeanQuery1(
1311 			new ThirdPartyProxy.ReqBeanQuery1Impl()
1312 		);
1313 		assertEquals("OK", r);
1314 	}
1315 
1316 	@ParameterizedTest
1317 	@MethodSource("input")
1318 	void gb02_reqBeanQuery2(Input input) {
1319 		var r = input.proxy.reqBeanQuery2(
1320 			new ThirdPartyProxy.ReqBeanQuery2()
1321 		);
1322 		assertEquals("OK", r);
1323 	}
1324 
1325 	@ParameterizedTest
1326 	@MethodSource("input")
1327 	void gb03_reqBeanQuery3(Input input) {
1328 		var r = input.proxy.reqBeanQuery3(
1329 			new ThirdPartyProxy.ReqBeanQuery3() {
1330 				@Override public int getX() { return 1; }
1331 				@Override public String getY() { return "foo"; }
1332 			}
1333 		);
1334 		assertEquals("OK", r);
1335 	}
1336 
1337 	@ParameterizedTest
1338 	@MethodSource("input")
1339 	void gb06_reqBeanQuery6(Input input) {
1340 		var r = input.proxy.reqBeanQuery6(
1341 			() -> map("a",1,"b","foo")
1342 		);
1343 		assertEquals("OK", r);
1344 	}
1345 
1346 	@ParameterizedTest
1347 	@MethodSource("input")
1348 	void gb07_reqBeanQuery7(Input input) {
1349 		var r = input.proxy.reqBeanQuery7(
1350 			ABean::get
1351 		);
1352 		assertEquals("OK", r);
1353 	}
1354 
1355 	//-----------------------------------------------------------------------------------------------------------------
1356 	// @Request tests - FormData
1357 	//-----------------------------------------------------------------------------------------------------------------
1358 
1359 	@ParameterizedTest
1360 	@MethodSource("input")
1361 	void gd01_reqBeanFormData1(Input input) {
1362 		var r = input.proxy.reqBeanFormData1(
1363 			new ThirdPartyProxy.ReqBeanFormData1() {
1364 				@Override public int getA() { return 1; }
1365 				@Override public String getB() { return "foo"; }
1366 			}
1367 		);
1368 		assertEquals("OK", r);
1369 	}
1370 
1371 	@ParameterizedTest
1372 	@MethodSource("input")
1373 	void gd01_reqBeanFormData1a(Input input) {
1374 		var r = input.proxy.reqBeanFormData1(
1375 			new ThirdPartyProxy.ReqBeanFormData1Impl()
1376 		);
1377 		assertEquals("OK", r);
1378 	}
1379 
1380 	@ParameterizedTest
1381 	@MethodSource("input")
1382 	void gd02_reqBeanFormData2(Input input) {
1383 		var r = input.proxy.reqBeanFormData2(
1384 			new ThirdPartyProxy.ReqBeanFormData2()
1385 		);
1386 		assertEquals("OK", r);
1387 	}
1388 
1389 	@ParameterizedTest
1390 	@MethodSource("input")
1391 	void gd03_reqBeanFormData3(Input input) {
1392 		var r = input.proxy.reqBeanFormData3(
1393 			new ThirdPartyProxy.ReqBeanFormData3() {
1394 				@Override public int getX() { return 1; }
1395 				@Override public String getY() { return "foo"; }
1396 			}
1397 		);
1398 		assertEquals("OK", r);
1399 	}
1400 
1401 	@ParameterizedTest
1402 	@MethodSource("input")
1403 	void gd06_reqBeanFormData6(Input input) {
1404 		var r = input.proxy.reqBeanFormData6(
1405 			() -> map("a",1,"b","foo")
1406 		);
1407 		assertEquals("OK", r);
1408 	}
1409 
1410 	@ParameterizedTest
1411 	@MethodSource("input")
1412 	void gd07_reqBeanFormData7(Input input) {
1413 		var r = input.proxy.reqBeanFormData7(
1414 			ABean::get
1415 		);
1416 		assertEquals("OK", r);
1417 	}
1418 
1419 	//-----------------------------------------------------------------------------------------------------------------
1420 	// @Request tests - Header
1421 	//-----------------------------------------------------------------------------------------------------------------
1422 
1423 	@ParameterizedTest
1424 	@MethodSource("input")
1425 	void gf01_reqBeanHeader1(Input input) {
1426 		var r = input.proxy.reqBeanHeader1(
1427 			new ThirdPartyProxy.ReqBeanHeader1() {
1428 				@Override public int getA() { return 1; }
1429 				@Override public String getB() { return "foo"; }
1430 			}
1431 		);
1432 		assertEquals("OK", r);
1433 	}
1434 
1435 	@ParameterizedTest
1436 	@MethodSource("input")
1437 	void gf01_reqBeanHeader1a(Input input) {
1438 		var r = input.proxy.reqBeanHeader1(
1439 			new ThirdPartyProxy.ReqBeanHeader1Impl()
1440 		);
1441 		assertEquals("OK", r);
1442 	}
1443 
1444 	@ParameterizedTest
1445 	@MethodSource("input")
1446 	void gf02_reqBeanHeader2(Input input) {
1447 		var r = input.proxy.reqBeanHeader2(
1448 			new ThirdPartyProxy.ReqBeanHeader2()
1449 		);
1450 		assertEquals("OK", r);
1451 	}
1452 
1453 	@ParameterizedTest
1454 	@MethodSource("input")
1455 	void gf03_reqBeanHeader3(Input input) {
1456 		var r = input.proxy.reqBeanHeader3(
1457 			new ThirdPartyProxy.ReqBeanHeader3() {
1458 				@Override public int getX() { return 1; }
1459 				@Override public String getY() { return "foo"; }
1460 			}
1461 		);
1462 		assertEquals("OK", r);
1463 	}
1464 
1465 	@ParameterizedTest
1466 	@MethodSource("input")
1467 	void gf06_reqBeanHeader6(Input input) {
1468 		var r = input.proxy.reqBeanHeader6(
1469 			() -> map("a",1,"b","foo")
1470 		);
1471 		assertEquals("OK", r);
1472 	}
1473 
1474 	@ParameterizedTest
1475 	@MethodSource("input")
1476 	void gf07_reqBeanHeader7(Input input) {
1477 		var r = input.proxy.reqBeanHeader7(
1478 			ABean::get
1479 		);
1480 		assertEquals("OK", r);
1481 	}
1482 
1483 	//-----------------------------------------------------------------------------------------------------------------
1484 	// PartFormatters
1485 	//-----------------------------------------------------------------------------------------------------------------
1486 	@ParameterizedTest
1487 	@MethodSource("input")
1488 	void h01(Input input) {
1489 		var r = input.proxy.partFormatters("1", "2", "3", "4");
1490 		assertEquals("OK", r);
1491 	}
1492 
1493 	//-----------------------------------------------------------------------------------------------------------------
1494 	// @RemoteOp(returns=HTTP_STATUS)
1495 	//-----------------------------------------------------------------------------------------------------------------
1496 	@ParameterizedTest
1497 	@MethodSource("input")
1498 	void i01a(Input input) {
1499 		var r = input.proxy.httpStatusReturnInt200();
1500 		assertEquals(200, r);
1501 	}
1502 
1503 	@ParameterizedTest
1504 	@MethodSource("input")
1505 	void i01b(Input input) {
1506 		var r = input.proxy.httpStatusReturnInteger200();
1507 		assertEquals(200, r.intValue());
1508 	}
1509 
1510 	@ParameterizedTest
1511 	@MethodSource("input")
1512 	void i01c(Input input) {
1513 		var r = input.proxy.httpStatusReturnInt404();
1514 		assertEquals(404, r);
1515 	}
1516 
1517 	@ParameterizedTest
1518 	@MethodSource("input")
1519 	void i01d(Input input) {
1520 		var r = input.proxy.httpStatusReturnInteger404();
1521 		assertEquals(404, r.intValue());
1522 	}
1523 
1524 	@ParameterizedTest
1525 	@MethodSource("input")
1526 	void i02a(Input input) {
1527 		var r = input.proxy.httpStatusReturnBool200();
1528 		assertEquals(true, r);
1529 	}
1530 
1531 	@ParameterizedTest
1532 	@MethodSource("input")
1533 	void i02b(Input input) {
1534 		var r = input.proxy.httpStatusReturnBoolean200();
1535 		assertEquals(true, r);
1536 	}
1537 
1538 	@ParameterizedTest
1539 	@MethodSource("input")
1540 	void i02c(Input input) {
1541 		var r = input.proxy.httpStatusReturnBool404();
1542 		assertEquals(false, r);
1543 	}
1544 
1545 	@ParameterizedTest
1546 	@MethodSource("input")
1547 	void i02d(Input input) {
1548 		var r = input.proxy.httpStatusReturnBoolean404();
1549 		assertEquals(false, r);
1550 	}
1551 
1552 	//-----------------------------------------------------------------------------------------------------------------
1553 	// Proxy class
1554 	//-----------------------------------------------------------------------------------------------------------------
1555 
1556 	@Remote
1557 	public interface ThirdPartyProxy {
1558 
1559 		//-------------------------------------------------------------------------------------------------------------
1560 		// Header tests
1561 		//-------------------------------------------------------------------------------------------------------------
1562 
1563 		@RemoteOp(method="GET", path="/primitiveHeaders")
1564 		String primitiveHeaders(
1565 			@Header("a") String a,
1566 			@Header("an") String an,
1567 			@Header("b") int b,
1568 			@Header("c") Integer c,
1569 			@Header("cn") Integer cn,
1570 			@Header("d") Boolean d,
1571 			@Header("e") float e,
1572 			@Header("f") Float f
1573 		);
1574 
1575 		@RemoteOp(method="GET", path="/primitiveCollectionHeaders")
1576 		String primitiveCollectionHeaders(
1577 			@Header("a") int[][][] a,
1578 			@Header("b") Integer[][][] b,
1579 			@Header("c") String[][][] c,
1580 			@Header("d") List<Integer> d,
1581 			@Header("e") List<List<List<Integer>>> e,
1582 			@Header("f") List<Integer[][][]> f,
1583 			@Header("g") List<int[][][]> g,
1584 			@Header("h") List<String> h
1585 		);
1586 
1587 		@RemoteOp(method="GET", path="/beanHeaders")
1588 		String beanHeaders(
1589 			@Header("a") ABean a,
1590 			@Header("an") ABean an,
1591 			@Header("b") ABean[][][] b,
1592 			@Header("c") List<ABean> c,
1593 			@Header("d") List<ABean[][][]> d,
1594 			@Header("e") Map<String,ABean> e,
1595 			@Header("f") Map<String,List<ABean>> f,
1596 			@Header("g") Map<String,List<ABean[][][]>> g,
1597 			@Header("h") Map<Integer,List<ABean>> h
1598 		);
1599 
1600 		@RemoteOp(method="GET", path="/typedBeanHeaders")
1601 		String typedBeanHeaders(
1602 			@Header("a") TypedBean a,
1603 			@Header("an") TypedBean an,
1604 			@Header("b") TypedBean[][][] b,
1605 			@Header("c") List<TypedBean> c,
1606 			@Header("d") List<TypedBean[][][]> d,
1607 			@Header("e") Map<String,TypedBean> e,
1608 			@Header("f") Map<String,List<TypedBean>> f,
1609 			@Header("g") Map<String,List<TypedBean[][][]>> g,
1610 			@Header("h") Map<Integer,List<TypedBean>> h
1611 		);
1612 
1613 		@RemoteOp(method="GET", path="/swappedObjectHeaders")
1614 		String swappedObjectHeaders(
1615 			@Header("a") SwappedObject a,
1616 			@Header("b") SwappedObject[][][] b,
1617 			@Header("c") Map<SwappedObject,SwappedObject> c,
1618 			@Header("d") Map<SwappedObject,SwappedObject[][][]> d
1619 		);
1620 
1621 		@RemoteOp(method="GET", path="/implicitSwappedObjectHeaders")
1622 		String implicitSwappedObjectHeaders(
1623 			@Header("a") ImplicitSwappedObject a,
1624 			@Header("b") ImplicitSwappedObject[][][] b,
1625 			@Header("c") Map<ImplicitSwappedObject,ImplicitSwappedObject> c,
1626 			@Header("d") Map<ImplicitSwappedObject,ImplicitSwappedObject[][][]> d
1627 		);
1628 
1629 		@RemoteOp(method="GET", path="/enumHeaders")
1630 		String enumHeaders(
1631 			@Header("a") TestEnum a,
1632 			@Header("an") TestEnum an,
1633 			@Header("b") TestEnum[][][] b,
1634 			@Header("c") List<TestEnum> c,
1635 			@Header("d") List<List<List<TestEnum>>> d,
1636 			@Header("e") List<TestEnum[][][]> e,
1637 			@Header("f") Map<TestEnum,TestEnum> f,
1638 			@Header("g") Map<TestEnum,TestEnum[][][]> g,
1639 			@Header("h") Map<TestEnum,List<TestEnum[][][]>> h
1640 		);
1641 
1642 		@RemoteOp(method="GET", path="/mapHeader")
1643 		String mapHeader(
1644 			@Header("*") Map<String,Object> a
1645 		);
1646 
1647 		@RemoteOp(method="GET", path="/beanHeader")
1648 		String beanHeader(
1649 			@Header("*") NeBean a
1650 		);
1651 
1652 		@RemoteOp(method="GET", path="/headerList")
1653 		String headerList(
1654 			@Header(value="*") @Schema(allowEmptyValue=true) HeaderList a
1655 		);
1656 
1657 		//-------------------------------------------------------------------------------------------------------------
1658 		// Query tests
1659 		//-------------------------------------------------------------------------------------------------------------
1660 
1661 		@RemoteOp(method="GET", path="/primitiveQueries")
1662 		String primitiveQueries(
1663 			@Query("a") String a,
1664 			@Query("an") String an,
1665 			@Query("b") int b,
1666 			@Query("c") Integer c,
1667 			@Query("cn") Integer cn,
1668 			@Query("d") Boolean d,
1669 			@Query("e") float e,
1670 			@Query("f") Float f
1671 		);
1672 
1673 		@RemoteOp(method="GET", path="/primitiveCollectionQueries")
1674 		String primitiveCollectionQueries(
1675 			@Query("a") int[][][] a,
1676 			@Query("b") Integer[][][] b,
1677 			@Query("c") String[][][] c,
1678 			@Query("d") List<Integer> d,
1679 			@Query("e") List<List<List<Integer>>> e,
1680 			@Query("f") List<Integer[][][]> f,
1681 			@Query("g") List<int[][][]> g,
1682 			@Query("h") List<String> h
1683 		);
1684 
1685 		@RemoteOp(method="GET", path="/beanQueries")
1686 		String beanQueries(
1687 			@Query("a") ABean a,
1688 			@Query("an") ABean an,
1689 			@Query("b") ABean[][][] b,
1690 			@Query("c") List<ABean> c,
1691 			@Query("d") List<ABean[][][]> d,
1692 			@Query("e") Map<String,ABean> e,
1693 			@Query("f") Map<String,List<ABean>> f,
1694 			@Query("g") Map<String,List<ABean[][][]>> g,
1695 			@Query("h") Map<Integer,List<ABean>> h
1696 		);
1697 
1698 		@RemoteOp(method="GET", path="/typedBeanQueries")
1699 		String typedBeanQueries(
1700 			@Query("a") TypedBean a,
1701 			@Query("an") TypedBean an,
1702 			@Query("b") TypedBean[][][] b,
1703 			@Query("c") List<TypedBean> c,
1704 			@Query("d") List<TypedBean[][][]> d,
1705 			@Query("e") Map<String,TypedBean> e,
1706 			@Query("f") Map<String,List<TypedBean>> f,
1707 			@Query("g") Map<String,List<TypedBean[][][]>> g,
1708 			@Query("h") Map<Integer,List<TypedBean>> h
1709 		);
1710 
1711 		@RemoteOp(method="GET", path="/swappedObjectQueries")
1712 		String swappedObjectQueries(
1713 			@Query("a") SwappedObject a,
1714 			@Query("b") SwappedObject[][][] b,
1715 			@Query("c") Map<SwappedObject,SwappedObject> c,
1716 			@Query("d") Map<SwappedObject,SwappedObject[][][]> d
1717 		);
1718 
1719 		@RemoteOp(method="GET", path="/implicitSwappedObjectQueries")
1720 		String implicitSwappedObjectQueries(
1721 			@Query("a") ImplicitSwappedObject a,
1722 			@Query("b") ImplicitSwappedObject[][][] b,
1723 			@Query("c") Map<ImplicitSwappedObject,ImplicitSwappedObject> c,
1724 			@Query("d") Map<ImplicitSwappedObject,ImplicitSwappedObject[][][]> d
1725 		);
1726 
1727 		@RemoteOp(method="GET", path="/enumQueries")
1728 		String enumQueries(
1729 			@Query("a") TestEnum a,
1730 			@Query("an") TestEnum an,
1731 			@Query("b") TestEnum[][][] b,
1732 			@Query("c") List<TestEnum> c,
1733 			@Query("d") List<List<List<TestEnum>>> d,
1734 			@Query("e") List<TestEnum[][][]> e,
1735 			@Query("f") Map<TestEnum,TestEnum> f,
1736 			@Query("g") Map<TestEnum,TestEnum[][][]> g,
1737 			@Query("h") Map<TestEnum,List<TestEnum[][][]>> h
1738 		);
1739 
1740 		@RemoteOp(method="GET", path="/stringQuery1")
1741 		String stringQuery1(
1742 			@Query String a
1743 		);
1744 
1745 		@RemoteOp(method="GET", path="/stringQuery2")
1746 		String stringQuery2(
1747 			@Query("*") String a
1748 		);
1749 
1750 		@RemoteOp(method="GET", path="/mapQuery")
1751 		String mapQuery(
1752 			@Query("*") Map<String,Object> a
1753 		);
1754 
1755 		@RemoteOp(method="GET", path="/beanQuery")
1756 		String beanQuery(
1757 			@Query("*") NeBean a
1758 		);
1759 
1760 		@RemoteOp(method="GET", path="/partListQuery")
1761 		String partListQuery(
1762 			@Query("*") PartList a
1763 		);
1764 
1765 		//-------------------------------------------------------------------------------------------------------------
1766 		// FormData tests
1767 		//-------------------------------------------------------------------------------------------------------------
1768 
1769 		@RemoteOp(method="POST", path="/primitiveFormData")
1770 		String primitiveFormData(
1771 			@FormData("a") String a,
1772 			@FormData("an") String an,
1773 			@FormData("b") int b,
1774 			@FormData("c") Integer c,
1775 			@FormData("cn") Integer cn,
1776 			@FormData("d") Boolean d,
1777 			@FormData("e") float e,
1778 			@FormData("f") Float f
1779 		);
1780 
1781 		@RemoteOp(method="POST", path="/primitiveCollectionFormData")
1782 		String primitiveCollectionFormData(
1783 			@FormData("a") int[][][] a,
1784 			@FormData("b") Integer[][][] b,
1785 			@FormData("c") String[][][] c,
1786 			@FormData("d") List<Integer> d,
1787 			@FormData("e") List<List<List<Integer>>> e,
1788 			@FormData("f") List<Integer[][][]> f,
1789 			@FormData("g") List<int[][][]> g,
1790 			@FormData("h") List<String> h
1791 		);
1792 
1793 		@RemoteOp(method="POST", path="/beanFormData")
1794 		String beanFormData(
1795 			@FormData("a") ABean a,
1796 			@FormData("an") ABean an,
1797 			@FormData("b") ABean[][][] b,
1798 			@FormData("c") List<ABean> c,
1799 			@FormData("d") List<ABean[][][]> d,
1800 			@FormData("e") Map<String,ABean> e,
1801 			@FormData("f") Map<String,List<ABean>> f,
1802 			@FormData("g") Map<String,List<ABean[][][]>> g,
1803 			@FormData("h") Map<Integer,List<ABean>> h
1804 		);
1805 
1806 		@RemoteOp(method="POST", path="/typedBeanFormData")
1807 		String typedBeanFormData(
1808 			@FormData("a") TypedBean a,
1809 			@FormData("an") TypedBean an,
1810 			@FormData("b") TypedBean[][][] b,
1811 			@FormData("c") List<TypedBean> c,
1812 			@FormData("d") List<TypedBean[][][]> d,
1813 			@FormData("e") Map<String,TypedBean> e,
1814 			@FormData("f") Map<String,List<TypedBean>> f,
1815 			@FormData("g") Map<String,List<TypedBean[][][]>> g,
1816 			@FormData("h") Map<Integer,List<TypedBean>> h
1817 		);
1818 
1819 		@RemoteOp(method="POST", path="/swappedObjectFormData")
1820 		String swappedObjectFormData(
1821 			@FormData("a") SwappedObject a,
1822 			@FormData("b") SwappedObject[][][] b,
1823 			@FormData("c") Map<SwappedObject,SwappedObject> c,
1824 			@FormData("d") Map<SwappedObject,SwappedObject[][][]> d
1825 		);
1826 
1827 		@RemoteOp(method="POST", path="/implicitSwappedObjectFormData")
1828 		String implicitSwappedObjectFormData(
1829 			@FormData("a") ImplicitSwappedObject a,
1830 			@FormData("b") ImplicitSwappedObject[][][] b,
1831 			@FormData("c") Map<ImplicitSwappedObject,ImplicitSwappedObject> c,
1832 			@FormData("d") Map<ImplicitSwappedObject,ImplicitSwappedObject[][][]> d
1833 		);
1834 
1835 		@RemoteOp(method="POST", path="/enumFormData")
1836 		String enumFormData(
1837 			@FormData("a") TestEnum a,
1838 			@FormData("an") TestEnum an,
1839 			@FormData("b") TestEnum[][][] b,
1840 			@FormData("c") List<TestEnum> c,
1841 			@FormData("d") List<List<List<TestEnum>>> d,
1842 			@FormData("e") List<TestEnum[][][]> e,
1843 			@FormData("f") Map<TestEnum,TestEnum> f,
1844 			@FormData("g") Map<TestEnum,TestEnum[][][]> g,
1845 			@FormData("h") Map<TestEnum,List<TestEnum[][][]>> h
1846 		);
1847 
1848 		@RemoteOp(method="POST", path="/mapFormData")
1849 		String mapFormData(
1850 			@FormData("*") Map<String,Object> a
1851 		);
1852 
1853 		@RemoteOp(method="POST", path="/beanFormData2")
1854 		String beanFormData(
1855 			@FormData("*") NeBean a
1856 		);
1857 
1858 		@RemoteOp(method="POST", path="/partListFormData")
1859 		String partListFormData(
1860 			@FormData("*") PartList a
1861 		);
1862 
1863 		//-------------------------------------------------------------------------------------------------------------
1864 		// Path tests
1865 		//-------------------------------------------------------------------------------------------------------------
1866 
1867 		@RemoteOp(method="POST", path="/pathVars1/{a}/{b}")
1868 		String pathVars1(
1869 			@Path("a") int a,
1870 			@Path("b") String b
1871 		);
1872 
1873 		@RemoteOp(method="POST", path="/pathVars2/{a}/{b}")
1874 		String pathVars2(
1875 			@Path Map<String,Object> a
1876 		);
1877 
1878 		@RemoteOp(method="POST", path="/pathVars3/{a}/{b}")
1879 		String pathVars3(
1880 			@Path ABean a
1881 		);
1882 
1883 		//-------------------------------------------------------------------------------------------------------------
1884 		// @Request tests - Path
1885 		//-------------------------------------------------------------------------------------------------------------
1886 
1887 		@RemoteOp(method="POST", path="/reqBeanPath/{a}/{b}")
1888 		String reqBeanPath1(
1889 			@Request ReqBeanPath1 rb
1890 		);
1891 
1892 		public interface ReqBeanPath1 {
1893 			@Path int getA();
1894 			@Path String getB();
1895 		}
1896 
1897 		public static class ReqBeanPath1Impl implements ReqBeanPath1 {
1898 			@Override public int getA() { return 1; }
1899 			@Override public String getB() { return "foo"; }
1900 		}
1901 
1902 
1903 		@RemoteOp(method="POST", path="/reqBeanPath/{a}/{b}")
1904 		String reqBeanPath2(
1905 			@Request ReqBeanPath2 rb
1906 		);
1907 
1908 		public static class ReqBeanPath2 {
1909 			@Path public int getA() { return 1; }
1910 			@Path public String getB() { return "foo"; }
1911 		}
1912 
1913 		@RemoteOp(method="POST", path="/reqBeanPath/{a}/{b}")
1914 		String reqBeanPath3(
1915 			@Request ReqBeanPath3 rb
1916 		);
1917 
1918 		public interface ReqBeanPath3 {
1919 			@Path("a") int getX();
1920 			@Path("b") String getY();
1921 		}
1922 
1923 		@RemoteOp(method="POST", path="/reqBeanPath/{a}/{b}")
1924 		String reqBeanPath6(
1925 			@Request ReqBeanPath6 rb
1926 		);
1927 
1928 		public interface ReqBeanPath6 {
1929 			@Path("*") Map<String,Object> getX();
1930 		}
1931 
1932 		@RemoteOp(method="POST", path="/reqBeanPath/{a}/{b}")
1933 		String reqBeanPath7(
1934 			@Request ReqBeanPath7 rb
1935 		);
1936 
1937 		public interface ReqBeanPath7 {
1938 			@Path("*") ABean getX();
1939 		}
1940 
1941 		//-------------------------------------------------------------------------------------------------------------
1942 		// @Request tests - Query
1943 		//-------------------------------------------------------------------------------------------------------------
1944 
1945 		@RemoteOp(method="POST", path="/reqBeanQuery")
1946 		String reqBeanQuery1(
1947 			@Request ReqBeanQuery1 rb
1948 		);
1949 
1950 		public interface ReqBeanQuery1 {
1951 			@Query int getA();
1952 			@Query String getB();
1953 		}
1954 
1955 		public static class ReqBeanQuery1Impl implements ReqBeanQuery1 {
1956 			@Override public int getA() { return 1; }
1957 			@Override public String getB() { return "foo"; }
1958 		}
1959 
1960 		@RemoteOp(method="POST", path="/reqBeanQuery")
1961 		String reqBeanQuery2(
1962 			@Request ReqBeanQuery2 rb
1963 		);
1964 
1965 		public static class ReqBeanQuery2 {
1966 			@Query public int getA() { return 1; }
1967 			@Query public String getB() { return "foo"; }
1968 		}
1969 
1970 		@RemoteOp(method="POST", path="/reqBeanQuery")
1971 		String reqBeanQuery3(
1972 			@Request ReqBeanQuery3 rb
1973 		);
1974 
1975 		public interface ReqBeanQuery3 {
1976 			@Query("a") int getX();
1977 			@Query("b") String getY();
1978 		}
1979 
1980 		@RemoteOp(method="POST", path="/reqBeanQuery")
1981 		String reqBeanQuery6(
1982 			@Request ReqBeanQuery6 rb
1983 		);
1984 
1985 		public interface ReqBeanQuery6 {
1986 			@Query("*") Map<String,Object> getX();
1987 		}
1988 
1989 		@RemoteOp(method="POST", path="/reqBeanQuery")
1990 		String reqBeanQuery7(
1991 			@Request ReqBeanQuery7 rb
1992 		);
1993 
1994 		public interface ReqBeanQuery7 {
1995 			@Query("*") ABean getX();
1996 		}
1997 
1998 		//-------------------------------------------------------------------------------------------------------------
1999 		// @Request tests - FormData
2000 		//-------------------------------------------------------------------------------------------------------------
2001 
2002 		@RemoteOp(method="POST", path="/reqBeanFormData")
2003 		String reqBeanFormData1(
2004 			@Request ReqBeanFormData1 rb
2005 		);
2006 
2007 		public interface ReqBeanFormData1 {
2008 			@FormData int getA();
2009 			@FormData String getB();
2010 		}
2011 
2012 		public static class ReqBeanFormData1Impl implements ReqBeanFormData1 {
2013 			@Override public int getA() { return 1; }
2014 			@Override public String getB() { return "foo"; }
2015 		}
2016 
2017 
2018 		@RemoteOp(method="POST", path="/reqBeanFormData")
2019 		String reqBeanFormData2(
2020 			@Request ReqBeanFormData2 rb
2021 		);
2022 
2023 		public static class ReqBeanFormData2 {
2024 			@FormData public int getA() { return 1; }
2025 			@FormData public String getB() { return "foo"; }
2026 		}
2027 
2028 		@RemoteOp(method="POST", path="/reqBeanFormData")
2029 		String reqBeanFormData3(
2030 			@Request ReqBeanFormData3 rb
2031 		);
2032 
2033 		public interface ReqBeanFormData3 {
2034 			@FormData("a") int getX();
2035 			@FormData("b") String getY();
2036 		}
2037 
2038 		@RemoteOp(method="POST", path="/reqBeanFormData")
2039 		String reqBeanFormData6(
2040 			@Request ReqBeanFormData6 rb
2041 		);
2042 
2043 		public interface ReqBeanFormData6 {
2044 			@FormData("*") Map<String,Object> getX();
2045 		}
2046 
2047 		@RemoteOp(method="POST", path="/reqBeanFormData")
2048 		String reqBeanFormData7(
2049 			@Request ReqBeanFormData7 rb
2050 		);
2051 
2052 		public interface ReqBeanFormData7 {
2053 			@FormData("*") ABean getX();
2054 		}
2055 
2056 		//-------------------------------------------------------------------------------------------------------------
2057 		// @Request tests - Header
2058 		//-------------------------------------------------------------------------------------------------------------
2059 
2060 		@RemoteOp(method="POST", path="/reqBeanHeader")
2061 		String reqBeanHeader1(
2062 			@Request ReqBeanHeader1 rb
2063 		);
2064 
2065 		public interface ReqBeanHeader1 {
2066 			@Header int getA();
2067 			@Header String getB();
2068 		}
2069 
2070 		public static class ReqBeanHeader1Impl implements ReqBeanHeader1 {
2071 			@Override public int getA() { return 1; }
2072 			@Override public String getB() { return "foo"; }
2073 		}
2074 
2075 		@RemoteOp(method="POST", path="/reqBeanHeader")
2076 		String reqBeanHeader2(
2077 			@Request ReqBeanHeader2 rb
2078 		);
2079 
2080 		public static class ReqBeanHeader2 {
2081 			@Header public int getA() { return 1; }
2082 			@Header public String getB() { return "foo"; }
2083 		}
2084 
2085 		@RemoteOp(method="POST", path="/reqBeanHeader")
2086 		String reqBeanHeader3(
2087 			@Request ReqBeanHeader3 rb
2088 		);
2089 
2090 		public interface ReqBeanHeader3 {
2091 			@Header("a") int getX();
2092 			@Header("b") String getY();
2093 		}
2094 
2095 		@RemoteOp(method="POST", path="/reqBeanHeader")
2096 		String reqBeanHeader6(
2097 			@Request ReqBeanHeader6 rb
2098 		);
2099 
2100 		public interface ReqBeanHeader6 {
2101 			@Header("*") Map<String,Object> getX();
2102 		}
2103 
2104 		@RemoteOp(method="POST", path="/reqBeanHeader")
2105 		String reqBeanHeader7(
2106 			@Request ReqBeanHeader7 rb
2107 		);
2108 
2109 		public interface ReqBeanHeader7 {
2110 			@Header("*") ABean getX();
2111 		}
2112 
2113 		//-------------------------------------------------------------------------------------------------------------
2114 		// PartFormatters
2115 		//-------------------------------------------------------------------------------------------------------------
2116 
2117 		@RemoteOp(method="POST", path="/partFormatters/{p1}")
2118 		String partFormatters(
2119 			@Path(value="p1", serializer=DummyPartSerializer.class) String p1,
2120 			@Header(value="h1", serializer=DummyPartSerializer.class) String h1,
2121 			@Query(value="q1", serializer=DummyPartSerializer.class) String q1,
2122 			@FormData(value="f1", serializer=DummyPartSerializer.class) String f1
2123 		);
2124 
2125 		//-------------------------------------------------------------------------------------------------------------
2126 		// Test return types.
2127 		//-------------------------------------------------------------------------------------------------------------
2128 
2129 		// Various primitives
2130 
2131 		@RemoteOp(method="GET", path="/returnVoid")
2132 		void returnVoid();
2133 
2134 		@RemoteOp(method="GET", path="/returnInt")
2135 		int returnInt();
2136 
2137 		@RemoteOp(method="GET", path="/returnInteger")
2138 		Integer returnInteger();
2139 
2140 		@RemoteOp(method="GET", path="/returnBoolean")
2141 		boolean returnBoolean();
2142 
2143 		@RemoteOp(method="GET", path="/returnFloat")
2144 		float returnFloat();
2145 
2146 		@RemoteOp(method="GET", path="/returnFloatObject")
2147 		Float returnFloatObject();
2148 
2149 		@RemoteOp(method="GET", path="/returnString")
2150 		String returnString();
2151 
2152 		@RemoteOp(method="GET", path="/returnNullString")
2153 		String returnNullString();
2154 
2155 		@RemoteOp(method="GET", path="/returnInt3dArray")
2156 		int[][][] returnInt3dArray();
2157 
2158 		@RemoteOp(method="GET", path="/returnInteger3dArray")
2159 		Integer[][][] returnInteger3dArray();
2160 
2161 		@RemoteOp(method="GET", path="/returnString3dArray")
2162 		String[][][] returnString3dArray();
2163 
2164 		@RemoteOp(method="GET", path="/returnIntegerList")
2165 		List<Integer> returnIntegerList();
2166 
2167 		@RemoteOp(method="GET", path="/returnInteger3dList")
2168 		List<List<List<Integer>>> returnInteger3dList();
2169 
2170 		@RemoteOp(method="GET", path="/returnInteger1d3dList")
2171 		List<Integer[][][]> returnInteger1d3dList();
2172 
2173 		@RemoteOp(method="GET", path="/returnInt1d3dList")
2174 		List<int[][][]> returnInt1d3dList();
2175 
2176 		@RemoteOp(method="GET", path="/returnStringList")
2177 		List<String> returnStringList();
2178 
2179 		// Beans
2180 
2181 		@RemoteOp(method="GET", path="/returnBean")
2182 		ABean returnBean();
2183 
2184 		@RemoteOp(method="GET", path="/returnBean3dArray")
2185 		ABean[][][] returnBean3dArray();
2186 
2187 		@RemoteOp(method="GET", path="/returnBeanList")
2188 		List<ABean> returnBeanList();
2189 
2190 		@RemoteOp(method="GET", path="/returnBean1d3dList")
2191 		List<ABean[][][]> returnBean1d3dList();
2192 
2193 		@RemoteOp(method="GET", path="/returnBeanMap")
2194 		Map<String,ABean> returnBeanMap();
2195 
2196 		@RemoteOp(method="GET", path="/returnBeanListMap")
2197 		Map<String,List<ABean>> returnBeanListMap();
2198 
2199 		@RemoteOp(method="GET", path="/returnBean1d3dListMap")
2200 		Map<String,List<ABean[][][]>> returnBean1d3dListMap();
2201 
2202 		@RemoteOp(method="GET", path="/returnBeanListMapIntegerKeys")
2203 		Map<Integer,List<ABean>> returnBeanListMapIntegerKeys();
2204 
2205 		// Typed beans
2206 
2207 		@RemoteOp(method="GET", path="/returnTypedBean")
2208 		TypedBean returnTypedBean();
2209 
2210 		@RemoteOp(method="GET", path="/returnTypedBean3dArray")
2211 		TypedBean[][][] returnTypedBean3dArray();
2212 
2213 		@RemoteOp(method="GET", path="/returnTypedBeanList")
2214 		List<TypedBean> returnTypedBeanList();
2215 
2216 		@RemoteOp(method="GET", path="/returnTypedBean1d3dList")
2217 		List<TypedBean[][][]> returnTypedBean1d3dList();
2218 
2219 		@RemoteOp(method="GET", path="/returnTypedBeanMap")
2220 		Map<String,TypedBean> returnTypedBeanMap();
2221 
2222 		@RemoteOp(method="GET", path="/returnTypedBeanListMap")
2223 		Map<String,List<TypedBean>> returnTypedBeanListMap();
2224 
2225 		@RemoteOp(method="GET", path="/returnTypedBean1d3dListMap")
2226 		Map<String,List<TypedBean[][][]>> returnTypedBean1d3dListMap();
2227 
2228 		@RemoteOp(method="GET", path="/returnTypedBeanListMapIntegerKeys")
2229 		Map<Integer,List<TypedBean>> returnTypedBeanListMapIntegerKeys();
2230 
2231 		// Swapped POJOs
2232 
2233 		@RemoteOp(method="GET", path="/returnSwappedObject")
2234 		SwappedObject returnSwappedObject();
2235 
2236 		@RemoteOp(method="GET", path="/returnSwappedObject3dArray")
2237 		SwappedObject[][][] returnSwappedObject3dArray();
2238 
2239 		@RemoteOp(method="GET", path="/returnSwappedObjectMap")
2240 		Map<SwappedObject,SwappedObject> returnSwappedObjectMap();
2241 
2242 		@RemoteOp(method="GET", path="/returnSwappedObject3dMap")
2243 		Map<SwappedObject,SwappedObject[][][]> returnSwappedObject3dMap();
2244 
2245 		// Implicit swapped POJOs
2246 
2247 		@RemoteOp(method="GET", path="/returnImplicitSwappedObject")
2248 		ImplicitSwappedObject returnImplicitSwappedObject();
2249 
2250 		@RemoteOp(method="GET", path="/returnImplicitSwappedObject3dArray")
2251 		ImplicitSwappedObject[][][] returnImplicitSwappedObject3dArray();
2252 
2253 		@RemoteOp(method="GET", path="/returnImplicitSwappedObjectMap")
2254 		Map<ImplicitSwappedObject,ImplicitSwappedObject> returnImplicitSwappedObjectMap();
2255 
2256 		@RemoteOp(method="GET", path="/returnImplicitSwappedObject3dMap")
2257 		Map<ImplicitSwappedObject,ImplicitSwappedObject[][][]> returnImplicitSwappedObject3dMap();
2258 
2259 		// Enums
2260 
2261 		@RemoteOp(method="GET", path="/returnEnum")
2262 		TestEnum returnEnum();
2263 
2264 		@RemoteOp(method="GET", path="/returnEnum3d")
2265 		TestEnum[][][] returnEnum3d();
2266 
2267 		@RemoteOp(method="GET", path="/returnEnumList")
2268 		List<TestEnum> returnEnumList();
2269 
2270 		@RemoteOp(method="GET", path="/returnEnum3dList")
2271 		List<List<List<TestEnum>>> returnEnum3dList();
2272 
2273 		@RemoteOp(method="GET", path="/returnEnum1d3dList")
2274 		List<TestEnum[][][]> returnEnum1d3dList();
2275 
2276 		@RemoteOp(method="GET", path="/returnEnumMap")
2277 		Map<TestEnum,TestEnum> returnEnumMap();
2278 
2279 		@RemoteOp(method="GET", path="/returnEnum3dArrayMap")
2280 		Map<TestEnum,TestEnum[][][]> returnEnum3dArrayMap();
2281 
2282 		@RemoteOp(method="GET", path="/returnEnum1d3dListMap")
2283 		Map<TestEnum,List<TestEnum[][][]>> returnEnum1d3dListMap();
2284 
2285 		//-------------------------------------------------------------------------------------------------------------
2286 		// Test parameters
2287 		//-------------------------------------------------------------------------------------------------------------
2288 
2289 		// Various primitives
2290 
2291 		@RemoteOp(method="POST", path="/setInt")
2292 		void setInt(@Content int x) throws AssertionFailedError;
2293 
2294 		@RemoteOp(method="POST", path="/setInteger")
2295 		void setInteger(@Content Integer x);
2296 
2297 		@RemoteOp(method="POST", path="/setBoolean")
2298 		void setBoolean(@Content boolean x);
2299 
2300 		@RemoteOp(method="POST", path="/setFloat")
2301 		void setFloat(@Content float x);
2302 
2303 		@RemoteOp(method="POST", path="/setFloatObject")
2304 		void setFloatObject(@Content Float x);
2305 
2306 		@RemoteOp(method="POST", path="/setString")
2307 		void setString(@Content String x);
2308 
2309 		@RemoteOp(method="POST", path="/setNullString")
2310 		void setNullString(@Content String x) throws AssertionFailedError;
2311 
2312 		@RemoteOp(method="POST", path="/setInt3dArray")
2313 		String setInt3dArray(@Content int[][][] x, @org.apache.juneau.http.annotation.Query("I") int i);
2314 
2315 		@RemoteOp(method="POST", path="/setInteger3dArray")
2316 		void setInteger3dArray(@Content Integer[][][] x);
2317 
2318 		@RemoteOp(method="POST", path="/setString3dArray")
2319 		void setString3dArray(@Content String[][][] x);
2320 
2321 		@RemoteOp(method="POST", path="/setIntegerList")
2322 		void setIntegerList(@Content List<Integer> x);
2323 
2324 		@RemoteOp(method="POST", path="/setInteger3dList")
2325 		void setInteger3dList(@Content List<List<List<Integer>>> x);
2326 
2327 		@RemoteOp(method="POST", path="/setInteger1d3dList")
2328 		void setInteger1d3dList(@Content List<Integer[][][]> x);
2329 
2330 		@RemoteOp(method="POST", path="/setInt1d3dList")
2331 		void setInt1d3dList(@Content List<int[][][]> x);
2332 
2333 		@RemoteOp(method="POST", path="/setStringList")
2334 		void setStringList(@Content List<String> x);
2335 
2336 		// Beans
2337 
2338 		@RemoteOp(method="POST", path="/setBean")
2339 		void setBean(@Content ABean x);
2340 
2341 		@RemoteOp(method="POST", path="/setBean3dArray")
2342 		void setBean3dArray(@Content ABean[][][] x);
2343 
2344 		@RemoteOp(method="POST", path="/setBeanList")
2345 		void setBeanList(@Content List<ABean> x);
2346 
2347 		@RemoteOp(method="POST", path="/setBean1d3dList")
2348 		void setBean1d3dList(@Content List<ABean[][][]> x);
2349 
2350 		@RemoteOp(method="POST", path="/setBeanMap")
2351 		void setBeanMap(@Content Map<String,ABean> x);
2352 
2353 		@RemoteOp(method="POST", path="/setBeanListMap")
2354 		void setBeanListMap(@Content Map<String,List<ABean>> x);
2355 
2356 		@RemoteOp(method="POST", path="/setBean1d3dListMap")
2357 		void setBean1d3dListMap(@Content Map<String,List<ABean[][][]>> x);
2358 
2359 		@RemoteOp(method="POST", path="/setBeanListMapIntegerKeys")
2360 		void setBeanListMapIntegerKeys(@Content Map<Integer,List<ABean>> x);
2361 
2362 		// Typed beans
2363 
2364 		@RemoteOp(method="POST", path="/setTypedBean")
2365 		void setTypedBean(@Content TypedBean x);
2366 
2367 		@RemoteOp(method="POST", path="/setTypedBean3dArray")
2368 		void setTypedBean3dArray(@Content TypedBean[][][] x);
2369 
2370 		@RemoteOp(method="POST", path="/setTypedBeanList")
2371 		void setTypedBeanList(@Content List<TypedBean> x);
2372 
2373 		@RemoteOp(method="POST", path="/setTypedBean1d3dList")
2374 		void setTypedBean1d3dList(@Content List<TypedBean[][][]> x);
2375 
2376 		@RemoteOp(method="POST", path="/setTypedBeanMap")
2377 		void setTypedBeanMap(@Content Map<String,TypedBean> x);
2378 
2379 		@RemoteOp(method="POST", path="/setTypedBeanListMap")
2380 		void setTypedBeanListMap(@Content Map<String,List<TypedBean>> x);
2381 
2382 		@RemoteOp(method="POST", path="/setTypedBean1d3dListMap")
2383 		void setTypedBean1d3dListMap(@Content Map<String,List<TypedBean[][][]>> x);
2384 
2385 		@RemoteOp(method="POST", path="/setTypedBeanListMapIntegerKeys")
2386 		void setTypedBeanListMapIntegerKeys(@Content Map<Integer,List<TypedBean>> x);
2387 
2388 		// Swapped POJOs
2389 
2390 		@RemoteOp(method="POST", path="/setSwappedObject")
2391 		void setSwappedObject(@Content SwappedObject x);
2392 
2393 		@RemoteOp(method="POST", path="/setSwappedObject3dArray")
2394 		void setSwappedObject3dArray(@Content SwappedObject[][][] x);
2395 
2396 		@RemoteOp(method="POST", path="/setSwappedObjectMap")
2397 		void setSwappedObjectMap(@Content Map<SwappedObject,SwappedObject> x);
2398 
2399 		@RemoteOp(method="POST", path="/setSwappedObject3dMap")
2400 		void setSwappedObject3dMap(@Content Map<SwappedObject,SwappedObject[][][]> x);
2401 
2402 		// Implicit swapped POJOs
2403 
2404 		@RemoteOp(method="POST", path="/setImplicitSwappedObject")
2405 		void setImplicitSwappedObject(@Content ImplicitSwappedObject x);
2406 
2407 		@RemoteOp(method="POST", path="/setImplicitSwappedObject3dArray")
2408 		void setImplicitSwappedObject3dArray(@Content ImplicitSwappedObject[][][] x);
2409 
2410 		@RemoteOp(method="POST", path="/setImplicitSwappedObjectMap")
2411 		void setImplicitSwappedObjectMap(@Content Map<ImplicitSwappedObject,ImplicitSwappedObject> x);
2412 
2413 		@RemoteOp(method="POST", path="/setImplicitSwappedObject3dMap")
2414 		void setImplicitSwappedObject3dMap(@Content Map<ImplicitSwappedObject,ImplicitSwappedObject[][][]> x);
2415 
2416 		// Enums
2417 
2418 		@RemoteOp(method="POST", path="/setEnum")
2419 		void setEnum(@Content TestEnum x);
2420 
2421 		@RemoteOp(method="POST", path="/setEnum3d")
2422 		void setEnum3d(@Content TestEnum[][][] x);
2423 
2424 		@RemoteOp(method="POST", path="/setEnumList")
2425 		void setEnumList(@Content List<TestEnum> x);
2426 
2427 		@RemoteOp(method="POST", path="/setEnum3dList")
2428 		void setEnum3dList(@Content List<List<List<TestEnum>>> x);
2429 
2430 		@RemoteOp(method="POST", path="/setEnum1d3dList")
2431 		void setEnum1d3dList(@Content List<TestEnum[][][]> x);
2432 
2433 		@RemoteOp(method="POST", path="/setEnumMap")
2434 		void setEnumMap(@Content Map<TestEnum,TestEnum> x);
2435 
2436 		@RemoteOp(method="POST", path="/setEnum3dArrayMap")
2437 		void setEnum3dArrayMap(@Content Map<TestEnum,TestEnum[][][]> x);
2438 
2439 		@RemoteOp(method="POST", path="/setEnum1d3dListMap")
2440 		void setEnum1d3dListMap(@Content Map<TestEnum,List<TestEnum[][][]>> x);
2441 
2442 		// Method returns status code
2443 
2444 		@RemoteOp(method="GET", path="/httpStatusReturn200", returns=RemoteReturn.STATUS)
2445 		int httpStatusReturnInt200();
2446 
2447 		@RemoteOp(method="GET", path="/httpStatusReturn200", returns=RemoteReturn.STATUS)
2448 		Integer httpStatusReturnInteger200();
2449 
2450 		@RemoteOp(method="GET", path="/httpStatusReturn404", returns=RemoteReturn.STATUS)
2451 		int httpStatusReturnInt404();
2452 
2453 		@RemoteOp(method="GET", path="/httpStatusReturn404", returns=RemoteReturn.STATUS)
2454 		Integer httpStatusReturnInteger404();
2455 
2456 		@RemoteOp(method="GET", path="/httpStatusReturn200", returns=RemoteReturn.STATUS)
2457 		boolean httpStatusReturnBool200();
2458 
2459 		@RemoteOp(method="GET", path="/httpStatusReturn200", returns=RemoteReturn.STATUS)
2460 		Boolean httpStatusReturnBoolean200();
2461 
2462 		@RemoteOp(method="GET", path="/httpStatusReturn404", returns=RemoteReturn.STATUS)
2463 		boolean httpStatusReturnBool404();
2464 
2465 		@RemoteOp(method="GET", path="/httpStatusReturn404", returns=RemoteReturn.STATUS)
2466 		Boolean httpStatusReturnBoolean404();
2467 	}
2468 
2469 	// Bean for testing NE annotations.
2470 	public static class NeBean {
2471 		public String a, b, c;
2472 
2473 		public NeBean init() {
2474 			this.a = "foo";
2475 			this.b = "";
2476 			this.c = null;
2477 			return this;
2478 		}
2479 	}
2480 
2481 	public static class DummyPartSerializer extends BaseHttpPartSerializer {
2482 		public DummyPartSerializer(Builder builder) {
2483 			super(builder);
2484 		}
2485 
2486 		public static Builder create() {
2487 			return new Builder();
2488 		}
2489 
2490 		public static class Builder extends BaseHttpPartSerializer.Builder {
2491 
2492 			Builder() {
2493 			}
2494 
2495 			Builder(Builder builder) {
2496 				super(builder);
2497 			}
2498 
2499 			@Override
2500 			public Builder copy() {
2501 				return new Builder(this);
2502 			}
2503 
2504 			@Override
2505 			public DummyPartSerializer build() {
2506 				return build(DummyPartSerializer.class);
2507 			}
2508 		}
2509 
2510 		@Override
2511 		public HttpPartSerializerSession getPartSession() {
2512 			return new BaseHttpPartSerializerSession() {
2513 				@Override
2514 				public String serialize(HttpPartType partType, HttpPartSchema schema, Object value) throws SerializeException, SchemaValidationException {
2515 					return "dummy-"+value;
2516 				}
2517 			};
2518 		}
2519 	}
2520 }