// ***************************************************************************************************************************
// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
// * with the License.  You may obtain a copy of the License at                                                              *
// *                                                                                                                         *
// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
// *                                                                                                                         *
// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
// * specific language governing permissions and limitations under the License.                                              *
// ***************************************************************************************************************************
package org.apache.juneau.rest.test.client;

import static org.apache.juneau.http.HttpMethodName.*;
import static org.apache.juneau.internal.ArrayUtils.*;
import static org.apache.juneau.internal.StringUtils.*;
import static org.junit.Assert.*;

import java.io.*;
import java.util.*;

import org.apache.juneau.http.annotation.*;
import org.apache.juneau.http.annotation.FormData;
import org.apache.juneau.http.annotation.Header;
import org.apache.juneau.http.annotation.Path;
import org.apache.juneau.http.annotation.Query;
import org.apache.juneau.httppart.*;
import org.apache.juneau.rest.*;
import org.apache.juneau.rest.annotation.*;
import org.apache.juneau.rest.client.*;
import org.apache.juneau.http.remote.*;
import org.apache.juneau.rest.mock2.*;
import org.apache.juneau.serializer.*;
import org.apache.juneau.uon.*;
import org.apache.juneau.urlencoding.*;
import org.apache.juneau.utils.*;
import org.junit.*;
import org.junit.runners.*;

@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class RequestBeanProxyTest {

	//=================================================================================================================
	// @Query
	//=================================================================================================================

	@Rest
	public static class A {
		@RestMethod(name=GET, path="/echoQuery")
		public String echoQuery(RestRequest req) throws Exception {
			return req.getQuery().toString(true);
		}
	}

	//=================================================================================================================
	// @Query - Simple values
	//=================================================================================================================

	@Remote(path="/")
	public static interface A01_RemoteResource {

		@RemoteMethod(method="GET", path="/echoQuery")
		String normal(@Request A01_BeanImpl rb);

		@RemoteMethod(method="GET", path="/echoQuery")
		String serialized(@Request(partSerializer=XSerializer.class) A01_BeanImpl rb);
	}

	public static interface A01_BeanInterface {
		@Query String getA();
		@Query("b") String getX1();
		@Query(name="c") String getX2();
		@Query(name="e",allowEmptyValue=true) String getX4();
		@Query("f") String getX5();
		@Query("g") String getX6();
		@Query("h") String getX7();
	}

	public static class A01_BeanImpl implements A01_BeanInterface {
		@Override public String getA() { return "a1"; }
		@Override public String getX1() { return "b1"; }
		@Override public String getX2() { return "c1"; }
		@Override public String getX4() { return ""; }
		@Override public String getX5() { return null; }
		@Override public String getX6() { return "true"; }
		@Override public String getX7() { return "123"; }
	}

	static A01_RemoteResource a01a = MockRemote.build(A01_RemoteResource.class, A.class, null);
	static A01_RemoteResource a01b = MockRestClient.create(A.class, null).partSerializer(UonSerializer.class).build().getRemote(A01_RemoteResource.class);

	@Test
	public void a01a_query_simpleVals_plainText() throws Exception {
		assertEquals("{a:'a1',b:'b1',c:'c1',e:'',g:'true',h:'123'}", a01a.normal(new A01_BeanImpl()));
	}
	@Test
	public void a01b_query_simpleVals_uon() throws Exception {
		assertEquals("{a:'a1',b:'b1',c:'c1',e:'',g:'\\'true\\'',h:'\\'123\\''}", a01b.normal(new A01_BeanImpl()));
	}
	@Test
	public void a01c_query_simpleVals_x() throws Exception {
		assertEquals("{a:'xa1x',b:'xb1x',c:'xc1x',e:'xx',g:'xtruex',h:'x123x'}", a01b.serialized(new A01_BeanImpl()));
	}

	//=================================================================================================================
	// @Query - Maps
	//=================================================================================================================

	@Remote(path="/")
	public static interface A02_RemoteResource {

		@RemoteMethod(method="GET", path="/echoQuery")
		String normal(@Request A02_Bean rb);

		@RemoteMethod(method="GET", path="/echoQuery")
		String serialized(@Request(partSerializer=XSerializer.class) A02_Bean rb);
	}

	public static class A02_Bean {
		@Query
		public Map<String,Object> getA() {
			return new AMap<String,Object>().append("a1","v1").append("a2", 123).append("a3", null).append("a4", "");
		}
		@Query("*")
		public Map<String,Object> getB() {
			return new AMap<String,Object>().append("b1","true").append("b2", "123").append("b3", "null");
		}
		@Query(name="*",allowEmptyValue=true)
		public Map<String,Object> getC() {
			return new AMap<String,Object>().append("c1","v1").append("c2", 123).append("c3", null).append("c4", "");
		}
		@Query("*")
		public Map<String,Object> getD() {
			return null;
		}
	}

	static A02_RemoteResource a02a = MockRemote.build(A02_RemoteResource.class, A.class, null);
	static A02_RemoteResource a02b = MockRestClient.create(A.class, null).partSerializer(UonSerializer.class).build().getRemote(A02_RemoteResource.class);

	@Test
	public void a02a_query_maps_plainText() throws Exception {
		String r = a02a.normal(new A02_Bean());
		assertEquals("{a:'(a1=v1,a2=123,a3=null,a4=\\'\\')',b1:'true',b2:'123',b3:'null',c1:'v1',c2:'123',c4:''}", r);
	}
	@Test
	public void a02b_query_maps_uon() throws Exception {
		String r = a02b.normal(new A02_Bean());
		assertEquals("{a:'(a1=v1,a2=123,a3=null,a4=\\'\\')',b1:'\\'true\\'',b2:'\\'123\\'',b3:'\\'null\\'',c1:'v1',c2:'123',c4:''}", r);
	}
	@Test
	public void a02c_query_maps_x() throws Exception {
		String r = a02b.serialized(new A02_Bean());
		assertEquals("{a:'x{a1=v1, a2=123, a3=null, a4=}x',b1:'xtruex',b2:'x123x',b3:'xnullx',c1:'xv1x',c2:'x123x',c4:'xx'}", r);
	}

	//=================================================================================================================
	// @Query - NameValuePairs
	//=================================================================================================================

	@Remote(path="/")
	public static interface A03_RemoteResource {

		@RemoteMethod(method="GET", path="/echoQuery")
		String normal(@Request A03_Bean rb);

		@RemoteMethod(method="GET", path="/echoQuery")
		String serialized(@Request(partSerializer=XSerializer.class) A03_Bean rb);
	}

	public static class A03_Bean {
		@Query(allowEmptyValue=true)
		public NameValuePairs getA() {
			return new NameValuePairs().append("a1","v1").append("a2", 123).append("a3", null).append("a4", "");
		}
		@Query("*")
		public NameValuePairs getB() {
			return new NameValuePairs().append("b1","true").append("b2", "123").append("b3", "null");
		}
		@Query(name="*",allowEmptyValue=true)
		public NameValuePairs getC() {
			return new NameValuePairs().append("c1","v1").append("c2", 123).append("c3", null).append("c4", "");
		}
		@Query("*")
		public NameValuePairs getD() {
			return null;
		}
	}

	static A03_RemoteResource a03a = MockRemote.build(A03_RemoteResource.class, A.class, null);
	static A03_RemoteResource a03b = MockRestClient.create(A.class, null).partSerializer(UonSerializer.class).build().getRemote(A03_RemoteResource.class);

	@Test
	public void a03a_query_nameValuePairs_plainText() throws Exception {
		String r = a03a.normal(new A03_Bean());
		assertEquals("{a1:'v1',a2:'123',a4:'',b1:'true',b2:'123',b3:'null',c1:'v1',c2:'123',c4:''}", r);
	}
	@Test
	public void a03b_query_nameValuePairs_on() throws Exception {
		String r = a03b.normal(new A03_Bean());
		assertEquals("{a1:'v1',a2:'\\'123\\'',a4:'',b1:'\\'true\\'',b2:'\\'123\\'',b3:'\\'null\\'',c1:'v1',c2:'\\'123\\'',c4:''}", r);
	}
	@Test
	public void a03c_query_nameValuePairs_x() throws Exception {
		String r = a03b.serialized(new A03_Bean());
		assertEquals("{a1:'xv1x',a2:'x123x',a4:'xx',b1:'xtruex',b2:'x123x',b3:'xnullx',c1:'xv1x',c2:'x123x',c4:'xx'}", r);
	}

	//=================================================================================================================
	// @Query - CharSequence
	//=================================================================================================================

	@Remote(path="/")
	public static interface A04_RemoteResource {
		@RemoteMethod(method="GET", path="/echoQuery")
		String normal(@Request A04_Bean rb);
	}

	public static class A04_Bean {
		@Query("*")
		public StringBuilder getA() {
			return new StringBuilder("foo=bar&baz=qux");
		}
	}

	static A04_RemoteResource a04a = MockRemote.build(A04_RemoteResource.class, A.class, null);

	@Test
	public void a04a_query_charSequence() throws Exception {
		String r = a04a.normal(new A04_Bean());
		assertEquals("{baz:'qux',foo:'bar'}", r);
	}

	//=================================================================================================================
	// @Query - Reader
	//=================================================================================================================

	@Remote(path="/")
	public static interface A05_RemoteResource {
		@RemoteMethod(method="GET", path="/echoQuery")
		String normal(@Request A05_Bean rb);
	}

	public static class A05_Bean {
		@Query("*")
		public Reader getA() {
			return new StringReader("foo=bar&baz=qux");
		}
	}

	static A05_RemoteResource a05a = MockRemote.build(A05_RemoteResource.class, A.class, null);

	@Test
	public void a05a_query_reader() throws Exception {
		String r = a05a.normal(new A05_Bean());
		assertEquals("{baz:'qux',foo:'bar'}", r);
	}

	//=================================================================================================================
	// @Query - Collections
	//=================================================================================================================

	@Remote(path="/")
	public static interface A06_RemoteResource {

		@RemoteMethod(method="GET", path="/echoQuery")
		String normal(@Request A06_Bean rb);

		@RemoteMethod(method="GET", path="/echoQuery")
		String serialized(@Request(partSerializer=XSerializer.class) A06_Bean rb);
	}

	public static class A06_Bean {
		@Query
		public List<Object> getA() {
			return new AList<>().append("foo").append("").append("true").append("123").append("null").append(true).append(123).append(null);
		}
		@Query("b")
		public List<Object> getX1() {
			return new AList<>().append("foo").append("").append("true").append("123").append("null").append(true).append(123).append(null);
		}
		@Query(name="c", serializer=ListSerializer.class)
		public List<Object> getX2() {
			return new AList<>().append("foo").append("").append("true").append("123").append("null").append(true).append(123).append(null);
		}
		@Query(name="d",allowEmptyValue=true)
		public List<Object> getX3() {
			return new AList<>();
		}
		@Query("e")
		public List<Object> getX4() {
			return null;
		}
		@Query("f")
		public Object[] getX5() {
			return new Object[]{"foo", "", "true", "123", "null", true, 123, null};
		}
		@Query(name="g", serializer=ListSerializer.class)
		public Object[] getX6() {
			return new Object[]{"foo", "", "true", "123", "null", true, 123, null};
		}
		@Query(name="h",allowEmptyValue=true)
		public Object[] getX7() {
			return new Object[]{};
		}
		@Query("i")
		public Object[] getX8() {
			return null;
		}
	}

	static A06_RemoteResource a06a = MockRemote.build(A06_RemoteResource.class, A.class, null);
	static A06_RemoteResource a06b = MockRestClient.create(A.class, null).partSerializer(UonSerializer.class).build().getRemote(A06_RemoteResource.class);

	@Test
	public void a06a_query_collections_plainText() throws Exception {
		String r = a06a.normal(new A06_Bean());
		assertEquals("{a:'foo,,true,123,null,true,123,null',b:'foo,,true,123,null,true,123,null',c:'foo||true|123|null|true|123|null',d:'',f:'foo,,true,123,null,true,123,null',g:'foo||true|123|null|true|123|null',h:''}", r);
	}
	@Test
	public void a06b_query_collections_uon() throws Exception {
		String r = a06b.normal(new A06_Bean());
		assertEquals("{a:'@(foo,\\'\\',\\'true\\',\\'123\\',\\'null\\',true,123,null)',b:'@(foo,\\'\\',\\'true\\',\\'123\\',\\'null\\',true,123,null)',c:'foo||true|123|null|true|123|null',d:'@()',f:'@(foo,\\'\\',\\'true\\',\\'123\\',\\'null\\',true,123,null)',g:'foo||true|123|null|true|123|null',h:'@()'}", r);
	}
	@Test
	public void a06c_query_collections_x() throws Exception {
		String r = a06b.serialized(new A06_Bean());
		assertEquals("{a:'fooXXtrueX123XnullXtrueX123Xnull',b:'fooXXtrueX123XnullXtrueX123Xnull',c:'foo||true|123|null|true|123|null',d:'',f:'fooXXtrueX123XnullXtrueX123Xnull',g:'foo||true|123|null|true|123|null',h:''}", r);
	}

	//=================================================================================================================
	// @FormData
	//=================================================================================================================

	@Rest(parsers=UrlEncodingParser.class)
	public static class C {
		@RestMethod(name=POST)
		public String echoFormData(RestRequest req) throws Exception {
			return req.getFormData().toString(true);
		}
	}

	//=================================================================================================================
	// @FormData, Simple values
	//=================================================================================================================

	@Remote(path="/")
	public static interface C01_RemoteResource {

		@RemoteMethod(method="POST", path="/echoFormData")
		String normal(@Request C01_Bean rb);

		@RemoteMethod(method="POST", path="/echoFormData")
		String serialized(@Request(partSerializer=XSerializer.class) C01_Bean rb);
	}

	public static class C01_Bean {
		@FormData
		public String getA() {
			return "a1";
		}
		@FormData("b")
		public String getX1() {
			return "b1";
		}
		@FormData(name="c")
		public String getX2() {
			return "c1";
		}
		@FormData(name="e",allowEmptyValue=true)
		public String getX4() {
			return "";
		}
		@FormData("f")
		public String getX5() {
			return null;
		}
		@FormData("g")
		public String getX6() {
			return "true";
		}
		@FormData("h")
		public String getX7() {
			return "123";
		}
	}

	static C01_RemoteResource c01a = MockRemote.build(C01_RemoteResource.class, C.class, null);
	static C01_RemoteResource c01b = MockRestClient.create(C.class, null).partSerializer(UonSerializer.class).build().getRemote(C01_RemoteResource.class);

	@Test
	public void c01a_formData_simpleVals_plainText() throws Exception {
		String r = c01a.normal(new C01_Bean());
		assertEquals("{a:'a1',b:'b1',c:'c1',e:'',g:'true',h:'123'}", r);
	}
	@Test
	public void c01b_formData_simpleVals_uon() throws Exception {
		String r = c01b.normal(new C01_Bean());
		assertEquals("{a:'a1',b:'b1',c:'c1',e:'',g:'\\'true\\'',h:'\\'123\\''}", r);
	}
	@Test
	public void c01c_formData_simpleVals_x() throws Exception {
		String r = c01b.serialized(new C01_Bean());
		assertEquals("{a:'xa1x',b:'xb1x',c:'xc1x',e:'xx',g:'xtruex',h:'x123x'}", r);
	}

	//=================================================================================================================
	// @FormData, Maps
	//=================================================================================================================

	@Remote(path="/")
	public static interface C02_RemoteResource {

		@RemoteMethod(method="POST", path="/echoFormData")
		String normal(@Request C02_Bean rb);

		@RemoteMethod(method="POST", path="/echoFormData")
		String serialized(@Request(partSerializer=XSerializer.class) C02_Bean rb);
	}

	public static class C02_Bean {
		@FormData
		public Map<String,Object> getA() {
			return new AMap<String,Object>().append("a1","v1").append("a2", 123).append("a3", null).append("a4", "");
		}
		@FormData("*")
		public Map<String,Object> getB() {
			return new AMap<String,Object>().append("b1","true").append("b2", "123").append("b3", "null");
		}
		@FormData(name="*",allowEmptyValue=true)
		public Map<String,Object> getC() {
			return new AMap<String,Object>().append("c1","v1").append("c2", 123).append("c3", null).append("c4", "");
		}
		@FormData("*")
		public Map<String,Object> getD() {
			return null;
		}
	}

	static C02_RemoteResource c02a = MockRemote.build(C02_RemoteResource.class, C.class, null);
	static C02_RemoteResource c02b = MockRestClient.create(C.class, null).partSerializer(UonSerializer.class).build().getRemote(C02_RemoteResource.class);

	@Test
	public void c02a_formData_maps_plainText() throws Exception {
		String r = c02a.normal(new C02_Bean());
		assertEquals("{a:'(a1=v1,a2=123,a3=null,a4=\\'\\')',b1:'true',b2:'123',b3:'null',c1:'v1',c2:'123',c4:''}", r);
	}
	@Test
	public void c02b_formData_maps_uon() throws Exception {
		String r = c02b.normal(new C02_Bean());
		assertEquals("{a:'(a1=v1,a2=123,a3=null,a4=\\'\\')',b1:'\\'true\\'',b2:'\\'123\\'',b3:'\\'null\\'',c1:'v1',c2:'123',c4:''}", r);
	}
	@Test
	public void c02c_formData_maps_x() throws Exception {
		String r = c02b.serialized(new C02_Bean());
		assertEquals("{a:'x{a1=v1, a2=123, a3=null, a4=}x',b1:'xtruex',b2:'x123x',b3:'xnullx',c1:'xv1x',c2:'x123x',c4:'xx'}", r);
	}

	//=================================================================================================================
	// @FormData, NameValuePairs
	//=================================================================================================================

	@Remote(path="/")
	public static interface C03_RemoteResource {

		@RemoteMethod(method="POST", path="/echoFormData")
		String normal(@Request C03_Bean rb);

		@RemoteMethod(method="POST", path="/echoFormData")
		String serialized(@Request(partSerializer=XSerializer.class) C03_Bean rb);
	}

	public static class C03_Bean {
		@FormData
		public NameValuePairs getA() {
			return new NameValuePairs().append("a1","v1").append("a2", 123).append("a3", null).append("a4", "");
		}
		@FormData("*")
		public NameValuePairs getB() {
			return new NameValuePairs().append("b1","true").append("b2", "123").append("b3", "null");
		}
		@FormData(name="*")
		public NameValuePairs getC() {
			return new NameValuePairs().append("c1","v1").append("c2", 123).append("c3", null).append("c4", "");
		}
		@FormData("*")
		public NameValuePairs getD() {
			return null;
		}
	}

	static C03_RemoteResource c03a = MockRemote.build(C03_RemoteResource.class, C.class, null);
	static C03_RemoteResource c03b = MockRestClient.create(C.class, null).partSerializer(UonSerializer.class).build().getRemote(C03_RemoteResource.class);

	@Test
	public void c03a_formData_nameValuePairs_plainText() throws Exception {
		String r = c03a.normal(new C03_Bean());
		assertEquals("{a1:'v1',a2:'123',a4:'',b1:'true',b2:'123',b3:'null',c1:'v1',c2:'123',c4:''}", r);
	}
	@Test
	public void c03b_formData_nameValuePairs_uon() throws Exception {
		String r = c03b.normal(new C03_Bean());
		assertEquals("{a1:'v1',a2:'123',a4:'',b1:'true',b2:'123',b3:'null',c1:'v1',c2:'123',c4:''}", r);
	}
	@Test
	public void c03c_formData_nameValuePairs_x() throws Exception {
		String r = c03b.serialized(new C03_Bean());
		assertEquals("{a1:'v1',a2:'123',a4:'',b1:'true',b2:'123',b3:'null',c1:'v1',c2:'123',c4:''}", r);
	}

	//=================================================================================================================
	// @FormData, CharSequence
	//=================================================================================================================

	@Remote(path="/")
	public static interface C04_RemoteResource {
		@RemoteMethod(method="POST", path="/echoFormData")
		String normal(@Request C04_Bean rb);
	}

	public static class C04_Bean {
		@FormData("*")
		public StringBuilder getA() {
			return new StringBuilder("foo=bar&baz=qux");
		}
	}

	static C04_RemoteResource c04a = MockRemote.build(C04_RemoteResource.class, C.class, null);

	@Test
	public void c04a_formDataCharSequence() throws Exception {
		String r = c04a.normal(new C04_Bean());
		assertEquals("{baz:'qux',foo:'bar'}", r);
	}

	//=================================================================================================================
	// @FormData, Reader
	//=================================================================================================================

	@Remote(path="/")
	public static interface C05_RemoteResource {
		@RemoteMethod(method="POST", path="/echoFormData")
		String normal(@Request C05_Bean rb);
	}

	public static class C05_Bean {
		@FormData("*")
		public Reader getA() {
			return new StringReader("foo=bar&baz=qux");
		}
	}

	static C05_RemoteResource c05a = MockRemote.build(C05_RemoteResource.class, C.class, null);

	@Test
	public void c05a_formDataReader() throws Exception {
		String r = c05a.normal(new C05_Bean());
		assertEquals("{baz:'qux',foo:'bar'}", r);
	}

	//=================================================================================================================
	// @FormData, Collections
	//=================================================================================================================

	@Remote(path="/")
	public static interface C06_RemoteResource {

		@RemoteMethod(method="POST", path="/echoFormData")
		String normal(@Request C06_Bean rb);

		@RemoteMethod(method="POST", path="/echoFormData")
		String serialized(@Request(partSerializer=XSerializer.class) C06_Bean rb);
	}

	public static class C06_Bean {
		@FormData
		public List<Object> getA() {
			return new AList<>().append("foo").append("").append("true").append("123").append("null").append(true).append(123).append(null);
		}
		@FormData("b")
		public List<Object> getX1() {
			return new AList<>().append("foo").append("").append("true").append("123").append("null").append(true).append(123).append(null);
		}
		@FormData(name="c", serializer=ListSerializer.class)
		public List<Object> getX2() {
			return new AList<>().append("foo").append("").append("true").append("123").append("null").append(true).append(123).append(null);
		}
		@FormData(name="d",allowEmptyValue=true)
		public List<Object> getX3() {
			return new AList<>();
		}
		@FormData("e")
		public List<Object> getX4() {
			return null;
		}
		@FormData("f")
		public Object[] getX5() {
			return new Object[]{"foo", "", "true", "123", "null", true, 123, null};
		}
		@FormData(name="g", serializer=ListSerializer.class)
		public Object[] getX6() {
			return new Object[]{"foo", "", "true", "123", "null", true, 123, null};
		}
		@FormData(name="h",allowEmptyValue=true)
		public Object[] getX7() {
			return new Object[]{};
		}
		@FormData("i")
		public Object[] getX8() {
			return null;
		}
	}

	static C06_RemoteResource c06a = MockRemote.build(C06_RemoteResource.class, C.class, null);
	static C06_RemoteResource c06b = MockRestClient.create(C.class, null).partSerializer(UonSerializer.class).build().getRemote(C06_RemoteResource.class);

	@Test
	public void c06a_formData_collections_plainText() throws Exception {
		String r = c06a.normal(new C06_Bean());
		assertEquals("{a:'foo,,true,123,null,true,123,null',b:'foo,,true,123,null,true,123,null',c:'foo||true|123|null|true|123|null',d:'',f:'foo,,true,123,null,true,123,null',g:'foo||true|123|null|true|123|null',h:''}", r);
	}
	@Test
	public void c06b_formData_collections_uon() throws Exception {
		String r = c06b.normal(new C06_Bean());
		assertEquals("{a:'@(foo,\\'\\',\\'true\\',\\'123\\',\\'null\\',true,123,null)',b:'@(foo,\\'\\',\\'true\\',\\'123\\',\\'null\\',true,123,null)',c:'foo||true|123|null|true|123|null',d:'@()',f:'@(foo,\\'\\',\\'true\\',\\'123\\',\\'null\\',true,123,null)',g:'foo||true|123|null|true|123|null',h:'@()'}", r);
	}
	@Test
	public void c06c_formData_collections_x() throws Exception {
		String r = c06b.serialized(new C06_Bean());
		assertEquals("{a:'fooXXtrueX123XnullXtrueX123Xnull',b:'fooXXtrueX123XnullXtrueX123Xnull',c:'foo||true|123|null|true|123|null',d:'',f:'fooXXtrueX123XnullXtrueX123Xnull',g:'foo||true|123|null|true|123|null',h:''}", r);
	}


	//=================================================================================================================
	// @Header
	//=================================================================================================================

	@Rest
	public static class E {
		@RestMethod(name=GET)
		public String echoHeaders(RestRequest req) throws Exception {
			return req.getHeaders().subset("a,b,c,d,e,f,g,h,i,a1,a2,a3,a4,b1,b2,b3,b4,c1,c2,c3,c4").toString(true);
		}
	}

	//=================================================================================================================
	// @Header, Simple values
	//=================================================================================================================

	@Remote(path="/")
	public static interface E01_RemoteResource {

		@RemoteMethod(method="GET", path="/echoHeaders")
		String normal(@Request E01_Bean rb);

		@RemoteMethod(method="GET", path="/echoHeaders")
		String serialized(@Request(partSerializer=XSerializer.class) E01_Bean rb);
	}

	public static class E01_Bean {
		@Header
		public String getA() {
			return "a1";
		}
		@Header("b")
		public String getX1() {
			return "b1";
		}
		@Header(name="c")
		public String getX2() {
			return "c1";
		}
		@Header(name="e",allowEmptyValue=true)
		public String getX4() {
			return "";
		}
		@Header("f")
		public String getX5() {
			return null;
		}
		@Header("g")
		public String getX6() {
			return "true";
		}
		@Header("h")
		public String getX7() {
			return "123";
		}
	}

	static E01_RemoteResource e01a = MockRemote.build(E01_RemoteResource.class, E.class, null);
	static E01_RemoteResource e01b = MockRestClient.create(E.class, null).partSerializer(UonSerializer.class).build().getRemote(E01_RemoteResource.class);

	@Test
	public void e01a_headerSimpleValsPlainText() throws Exception {
		String r = e01a.normal(new E01_Bean());
		assertEquals("{a:'a1',b:'b1',c:'c1',e:'',g:'true',h:'123'}", r);
	}
	@Test
	public void e01b_headerSimpleValsUon() throws Exception {
		String r = e01b.normal(new E01_Bean());
		assertEquals("{a:'a1',b:'b1',c:'c1',e:'',g:'\\'true\\'',h:'\\'123\\''}", r);
	}
	@Test
	public void e01c_headerSimpleValsX() throws Exception {
		String r = e01b.serialized(new E01_Bean());
		assertEquals("{a:'xa1x',b:'xb1x',c:'xc1x',e:'xx',g:'xtruex',h:'x123x'}", r);
	}

	//=================================================================================================================
	// @Header, Maps
	//=================================================================================================================

	@Remote(path="/")
	public static interface E02_RemoteResource {

		@RemoteMethod(method="GET", path="/echoHeaders")
		String normal(@Request E02_Bean rb);

		@RemoteMethod(method="GET", path="/echoHeaders")
		String serialized(@Request(partSerializer=XSerializer.class) E02_Bean rb);
	}

	public static class E02_Bean {
		@Header
		public Map<String,Object> getA() {
			return new AMap<String,Object>().append("a1","v1").append("a2", 123).append("a3", null).append("a4", "");
		}
		@Header("*")
		public Map<String,Object> getB() {
			return new AMap<String,Object>().append("b1","true").append("b2", "123").append("b3", "null");
		}
		@Header(name="*",allowEmptyValue=true)
		public Map<String,Object> getC() {
			return new AMap<String,Object>().append("c1","v1").append("c2", 123).append("c3", null).append("c4", "");
		}
		@Header("*")
		public Map<String,Object> getD() {
			return null;
		}
	}

	static E02_RemoteResource e02a = MockRemote.build(E02_RemoteResource.class, E.class, null);
	static E02_RemoteResource e02b = MockRestClient.create(E.class, null).partSerializer(UonSerializer.class).build().getRemote(E02_RemoteResource.class);

	@Test
	public void e02a_header_maps_plainText() throws Exception {
		String r = e02a.normal(new E02_Bean());
		assertEquals("{a:'(a1=v1,a2=123,a3=null,a4=\\'\\')',b1:'true',b2:'123',b3:'null',c1:'v1',c2:'123',c4:''}", r);
	}
	@Test
	public void e02b_header_maps_uon() throws Exception {
		String r = e02b.normal(new E02_Bean());
		assertEquals("{a:'(a1=v1,a2=123,a3=null,a4=\\'\\')',b1:'\\'true\\'',b2:'\\'123\\'',b3:'\\'null\\'',c1:'v1',c2:'123',c4:''}", r);
	}
	@Test
	public void e02c_header_maps_x() throws Exception {
		String r = e02b.serialized(new E02_Bean());
		assertEquals("{a:'x{a1=v1, a2=123, a3=null, a4=}x',b1:'xtruex',b2:'x123x',b3:'xnullx',c1:'xv1x',c2:'x123x',c4:'xx'}", r);
	}

	//=================================================================================================================
	// @Header, NameValuePairs
	//=================================================================================================================

	@Remote(path="/")
	public static interface E03_RemoteResource {

		@RemoteMethod(method="GET", path="/echoHeaders")
		String normal(@Request E03_Bean rb);

		@RemoteMethod(method="GET", path="/echoHeaders")
		String serialized(@Request(partSerializer=XSerializer.class) E03_Bean rb);
	}

	public static class E03_Bean {
		@Header(allowEmptyValue=true)
		public NameValuePairs getA() {
			return new NameValuePairs().append("a1","v1").append("a2", 123).append("a3", null).append("a4", "");
		}
		@Header(value="*",allowEmptyValue=true)
		public NameValuePairs getB() {
			return new NameValuePairs().append("b1","true").append("b2", "123").append("b3", "null");
		}
		@Header(name="*",allowEmptyValue=true)
		public NameValuePairs getC() {
			return new NameValuePairs().append("c1","v1").append("c2", 123).append("c3", null).append("c4", "");
		}
		@Header(value="*",allowEmptyValue=true)
		public NameValuePairs getD() {
			return null;
		}
	}

	static E03_RemoteResource e03a = MockRemote.build(E03_RemoteResource.class, E.class, null);
	static E03_RemoteResource e03b = MockRestClient.create(E.class, null).partSerializer(UonSerializer.class).build().getRemote(E03_RemoteResource.class);

	@Test
	public void e03a_header_nameValuePairs_plainText() throws Exception {
		String r = e03a.normal(new E03_Bean());
		assertEquals("{a1:'v1',a2:'123',a4:'',b1:'true',b2:'123',b3:'null',c1:'v1',c2:'123',c4:''}", r);
	}
	@Test
	public void e03b_header_nameValuePairs_uon() throws Exception {
		String r = e03b.normal(new E03_Bean());
		assertEquals("{a1:'v1',a2:'\\'123\\'',a4:'',b1:'\\'true\\'',b2:'\\'123\\'',b3:'\\'null\\'',c1:'v1',c2:'\\'123\\'',c4:''}", r);
	}
	@Test
	public void e03c_header_nameValuePairs_x() throws Exception {
		String r = e03b.serialized(new E03_Bean());
		assertEquals("{a1:'xv1x',a2:'x123x',a4:'xx',b1:'xtruex',b2:'x123x',b3:'xnullx',c1:'xv1x',c2:'x123x',c4:'xx'}", r);
	}

	//=================================================================================================================
	// @Header, Collections
	//=================================================================================================================

	@Remote(path="/")
	public static interface E04_RemoteResource {

		@RemoteMethod(method="GET", path="/echoHeaders")
		String normal(@Request E04_Bean rb);

		@RemoteMethod(method="GET", path="/echoHeaders")
		String serialized(@Request(partSerializer=XSerializer.class) E04_Bean rb);
	}

	public static class E04_Bean {
		@Header
		public List<Object> getA() {
			return new AList<>().append("foo").append("").append("true").append("123").append("null").append(true).append(123).append(null);
		}
		@Header("b")
		public List<Object> getX1() {
			return new AList<>().append("foo").append("").append("true").append("123").append("null").append(true).append(123).append(null);
		}
		@Header(name="c", serializer=ListSerializer.class)
		public List<Object> getX2() {
			return new AList<>().append("foo").append("").append("true").append("123").append("null").append(true).append(123).append(null);
		}
		@Header(name="d",allowEmptyValue=true)
		public List<Object> getX3() {
			return new AList<>();
		}
		@Header("e")
		public List<Object> getX4() {
			return null;
		}
		@Header("f")
		public Object[] getX5() {
			return new Object[]{"foo", "", "true", "123", "null", true, 123, null};
		}
		@Header(name="g", serializer=ListSerializer.class)
		public Object[] getX6() {
			return new Object[]{"foo", "", "true", "123", "null", true, 123, null};
		}
		@Header(name="h",allowEmptyValue=true)
		public Object[] getX7() {
			return new Object[]{};
		}
		@Header("i")
		public Object[] getX8() {
			return null;
		}
	}

	static E04_RemoteResource e04a = MockRemote.build(E04_RemoteResource.class, E.class, null);
	static E04_RemoteResource e04b = MockRestClient.create(E.class, null).partSerializer(UonSerializer.class).build().getRemote(E04_RemoteResource.class);

	@Test
	public void e04a_header_collections_plainText() throws Exception {
		String r = e04a.normal(new E04_Bean());
		assertEquals("{a:'foo,,true,123,null,true,123,null',b:'foo,,true,123,null,true,123,null',c:'foo||true|123|null|true|123|null',d:'',f:'foo,,true,123,null,true,123,null',g:'foo||true|123|null|true|123|null',h:''}", r);
	}
	@Test
	public void e04b_header_collections_uon() throws Exception {
		String r = e04b.normal(new E04_Bean());
		assertEquals("{a:'@(foo,\\'\\',\\'true\\',\\'123\\',\\'null\\',true,123,null)',b:'@(foo,\\'\\',\\'true\\',\\'123\\',\\'null\\',true,123,null)',c:'foo||true|123|null|true|123|null',d:'@()',f:'@(foo,\\'\\',\\'true\\',\\'123\\',\\'null\\',true,123,null)',g:'foo||true|123|null|true|123|null',h:'@()'}", r);
	}
	@Test
	public void e04c_header_collections_x() throws Exception {
		String r = e04b.serialized(new E04_Bean());
		assertEquals("{a:'fooXXtrueX123XnullXtrueX123Xnull',b:'fooXXtrueX123XnullXtrueX123Xnull',c:'foo||true|123|null|true|123|null',d:'',f:'fooXXtrueX123XnullXtrueX123Xnull',g:'foo||true|123|null|true|123|null',h:''}", r);
	}

	//=================================================================================================================
	// @Path
	//=================================================================================================================

	@Rest
	public static class G  {
		@RestMethod(name=GET,path="/*")
		public String echoPath(RestRequest req) throws Exception {
			return req.getPathMatch().getRemainder();
		}
	}

	//=================================================================================================================
	// @Path, Simple values
	//=================================================================================================================

	@Remote(path="/")
	public static interface G01_RemoteResource {

		@RemoteMethod(method="GET", path="/echoPath/{a}/{b}/{c}/{e}/{g}/{h}")
		String normal(@Request G01_Bean rb);

		@RemoteMethod(method="GET", path="/echoPath/{a}/{b}/{c}/{e}/{g}/{h}")
		String serialized(@Request(partSerializer=XSerializer.class) G01_Bean rb);
	}

	public static class G01_Bean {
		@Path
		public String getA() {
			return "a1";
		}
		@Path("b")
		public String getX1() {
			return "b1";
		}
		@Path(name="c")
		public String getX2() {
			return "c1";
		}
		@Path(name="e",allowEmptyValue=true)
		public String getX4() {
			return "";
		}
		@Path("g")
		public String getX6() {
			return "true";
		}
		@Path("h")
		public String getX7() {
			return "123";
		}
	}

	static G01_RemoteResource g01a = MockRemote.build(G01_RemoteResource.class, G.class, null);
	static G01_RemoteResource g01b = MockRestClient.create(G.class, null).partSerializer(UonSerializer.class).build().getRemote(G01_RemoteResource.class);

	@Test
	public void g01a_pathSimpleValsPlainText() throws Exception {
		String r = g01a.normal(new G01_Bean());
		assertEquals("echoPath/a1/b1/c1//true/123", r);
	}
	@Test
	public void g01b_pathSimpleValsUon() throws Exception {
		String r = g01b.normal(new G01_Bean());
		assertEquals("echoPath/a1/b1/c1//'true'/'123'", r);
	}
	@Test
	public void g01c_pathSimpleValsX() throws Exception {
		String r = g01b.serialized(new G01_Bean());
		assertEquals("echoPath/xa1x/xb1x/xc1x/xx/xtruex/x123x", r);
	}

	//=================================================================================================================
	// @Path, Maps
	//=================================================================================================================

	@Remote(path="/")
	public static interface G02_RemoteResource {

		@RemoteMethod(method="GET", path="/echoPath/{a1}/{a2}/{a3}/{a4}/{b1}/{b2}/{b3}/{c1}/{c2}/{c3}/{c4}")
		String normal(@Request G02_Bean rb);

		@RemoteMethod(method="GET", path="/echoPath/{a1}/{a2}/{a3}/{a4}/{b1}/{b2}/{b3}/{c1}/{c2}/{c3}/{c4}")
		String serialized(@Request(partSerializer=XSerializer.class) G02_Bean rb);
	}

	public static class G02_Bean {
		@Path(name="*",allowEmptyValue=true)
		public Map<String,Object> getA() {
			return new AMap<String,Object>().append("a1","v1").append("a2", 123).append("a3", null).append("a4", "");
		}
		@Path("*")
		public Map<String,Object> getB() {
			return new AMap<String,Object>().append("b1","true").append("b2", "123").append("b3", "null");
		}
		@Path(name="*",allowEmptyValue=true)
		public Map<String,Object> getC() {
			return new AMap<String,Object>().append("c1","v1").append("c2", 123).append("c3", null).append("c4", "");
		}
		@Path("*")
		public Map<String,Object> getD() {
			return null;
		}
	}

	static G02_RemoteResource g02a = MockRemote.build(G02_RemoteResource.class, G.class, null);
	static G02_RemoteResource g02b = MockRestClient.create(G.class, null).partSerializer(UonSerializer.class).build().getRemote(G02_RemoteResource.class);

	@Test
	public void g02a_path_maps_plainText() throws Exception {
		String r = g02a.normal(new G02_Bean());
		assertEquals("echoPath/v1/123/null//true/123/null/v1/123/null/", r);
	}
	@Test
	public void g02b_path_maps_uon() throws Exception {
		String r = g02b.normal(new G02_Bean());
		assertEquals("echoPath/v1/123/null//'true'/'123'/'null'/v1/123/null/", r);
	}
	@Test
	public void g02c_path_maps_x() throws Exception {
		String r = g02b.serialized(new G02_Bean());
		assertEquals("echoPath/xv1x/x123x/NULL/xx/xtruex/x123x/xnullx/xv1x/x123x/NULL/xx", r);
	}

	//=================================================================================================================
	// @Path, NameValuePairs
	//=================================================================================================================

	@Remote(path="/")
	public static interface G03_RemoteResource {

		@RemoteMethod(method="GET", path="/echoPath/{a1}/{a2}/{a3}/{a4}/{b1}/{b2}/{b3}/{c1}/{c2}/{c3}/{c4}")
		String normal(@Request G03_Bean rb);

		@RemoteMethod(method="GET", path="/echoPath/{a1}/{a2}/{a3}/{a4}/{b1}/{b2}/{b3}/{c1}/{c2}/{c3}/{c4}")
		String serialized(@Request(partSerializer=XSerializer.class) G03_Bean rb);
	}

	public static class G03_Bean {
		@Path(name="*",allowEmptyValue=true)
		public NameValuePairs getA() {
			return new NameValuePairs().append("a1","v1").append("a2", 123).append("a3", null).append("a4", "");
		}
		@Path("/*")
		public NameValuePairs getB() {
			return new NameValuePairs().append("b1","true").append("b2", "123").append("b3", "null");
		}
		@Path(name="*",allowEmptyValue=true)
		public NameValuePairs getC() {
			return new NameValuePairs().append("c1","v1").append("c2", 123).append("c3", null).append("c4", "");
		}
		@Path("/*")
		public NameValuePairs getD() {
			return null;
		}
	}

	static G03_RemoteResource g03a = MockRemote.build(G03_RemoteResource.class, G.class, null);
	static G03_RemoteResource g03b = MockRestClient.create(G.class, null).partSerializer(UonSerializer.class).build().getRemote(G03_RemoteResource.class);

	@Test
	public void g03a_path_nameValuePairs_plainText() throws Exception {
		String r = g03a.normal(new G03_Bean());
		assertEquals("echoPath/v1/123/null//true/123/null/v1/123/null/", r);
	}
	@Test
	public void g03b_path_nameValuePairs_uon() throws Exception {
		String r = g03b.normal(new G03_Bean());
		assertEquals("echoPath/v1/'123'/null//'true'/'123'/'null'/v1/'123'/null/", r);
	}
	@Test
	public void g03c_path_nameValuePairs_x() throws Exception {
		String r = g03b.serialized(new G03_Bean());
		assertEquals("echoPath/xv1x/x123x/NULL/xx/xtruex/x123x/xnullx/xv1x/x123x/NULL/xx", r);
	}

	//=================================================================================================================
	// @Path, Collections
	//=================================================================================================================

	@Remote(path="/")
	public static interface G04_RemoteResource {

		@RemoteMethod(method="GET", path="/echoPath/{a}/{b}/{c}/{d}/{f}/{g}/{h}")
		String normal(@Request G04_Bean rb);

		@RemoteMethod(method="GET", path="/echoPath/{a}/{b}/{c}/{d}/{f}/{g}/{h}")
		String serialized(@Request(partSerializer=XSerializer.class) G04_Bean rb);
	}

	public static class G04_Bean {
		@Path
		public List<Object> getA() {
			return new AList<>().append("foo").append("").append("true").append("123").append("null").append(true).append(123).append(null);
		}
		@Path("b")
		public List<Object> getX1() {
			return new AList<>().append("foo").append("").append("true").append("123").append("null").append(true).append(123).append(null);
		}
		@Path(name="c", serializer=ListSerializer.class)
		public List<Object> getX2() {
			return new AList<>().append("foo").append("").append("true").append("123").append("null").append(true).append(123).append(null);
		}
		@Path(name="d",allowEmptyValue=true)
		public List<Object> getX3() {
			return new AList<>();
		}
		@Path("f")
		public Object[] getX5() {
			return new Object[]{"foo", "", "true", "123", "null", true, 123, null};
		}
		@Path(name="g", serializer=ListSerializer.class)
		public Object[] getX6() {
			return new Object[]{"foo", "", "true", "123", "null", true, 123, null};
		}
		@Path(name="h",allowEmptyValue=true)
		public Object[] getX7() {
			return new Object[]{};
		}
	}

	static G04_RemoteResource g04a = MockRemote.build(G04_RemoteResource.class, G.class, null);
	static G04_RemoteResource g04b = MockRestClient.create(G.class, null).partSerializer(UonSerializer.class).build().getRemote(G04_RemoteResource.class);

	@Test
	public void g04a_path_collections_plainText() throws Exception {
		String r = g04a.normal(new G04_Bean());
		assertEquals("echoPath/foo,,true,123,null,true,123,null/foo,,true,123,null,true,123,null/foo||true|123|null|true|123|null//foo,,true,123,null,true,123,null/foo||true|123|null|true|123|null/", r);
	}
	@Test
	public void g04b_path_collections_uon() throws Exception {
		String r = g04b.normal(new G04_Bean());
		assertEquals("echoPath/@(foo,'','true','123','null',true,123,null)/@(foo,'','true','123','null',true,123,null)/foo||true|123|null|true|123|null/@()/@(foo,'','true','123','null',true,123,null)/foo||true|123|null|true|123|null/@()", r);
	}
	@Test
	public void g04c_path_collections_x() throws Exception {
		String r = g04b.serialized(new G04_Bean());
		assertEquals("echoPath/fooXXtrueX123XnullXtrueX123Xnull/fooXXtrueX123XnullXtrueX123Xnull/foo||true|123|null|true|123|null//fooXXtrueX123XnullXtrueX123Xnull/foo||true|123|null|true|123|null/", r);
	}

	//=================================================================================================================
	// Support classes
	//=================================================================================================================

	public static class XSerializer extends BaseHttpPartSerializer {
		@Override
		public HttpPartSerializerSession createPartSession(SerializerSessionArgs args) {
			return new BaseHttpPartSerializerSession() {
				@Override
				public String serialize(HttpPartType partType, HttpPartSchema schema, Object value) throws SerializeException, SchemaValidationException {
					if (value == null)
						return "NULL";
					if (value instanceof Collection)
						return join((Collection<?>)value, "X");
					if (isArray(value))
						return join(toList(value, Object.class), "X");
					return "x" + value + "x";
				}
			};
		}

		@Override
		public String serialize(HttpPartType partType, HttpPartSchema schema, Object value) throws SchemaValidationException, SerializeException {
			return createPartSession().serialize(partType, schema, value);
		}

		@Override
		public String serialize(HttpPartSchema schema, Object value) throws SchemaValidationException, SerializeException {
			return createPartSession().serialize(null, schema, value);
		}
	}

	public static class ListSerializer extends BaseHttpPartSerializer {
		@Override
		public HttpPartSerializerSession createPartSession(SerializerSessionArgs args) {
			return new BaseHttpPartSerializerSession() {
				@Override
				public String serialize(HttpPartType partType, HttpPartSchema schema, Object value) throws SerializeException, SchemaValidationException {
					if (value == null)
						return "NULL";
					if (value instanceof Collection)
						return join((Collection<?>)value, '|');
					if (isArray(value))
						return join(toList(value, Object.class), "|");
					return "?" + value + "?";
				}
			};
		}

		@Override
		public String serialize(HttpPartType partType, HttpPartSchema schema, Object value) throws SchemaValidationException, SerializeException {
			return createPartSession().serialize(partType, schema, value);
		}

		@Override
		public String serialize(HttpPartSchema schema, Object value) throws SchemaValidationException, SerializeException {
			return createPartSession().serialize(null, schema, value);
		}
	}
}
