using System;
using System.Linq;
using System.Runtime.CompilerServices;
using Microsoft.CSharp.RuntimeBinder; // Requires reference to Microsoft.CSharp
public class ImplicitTest
{
public double Val { get; set; }
public ImplicitTest(double val)
{
this.Val = val;
}
public static implicit operator int(ImplicitTest d)
{
return (int)d.Val;
}
}
public class TestClass
{
public int Val { get; set; }
public TestClass(int val = 5)
{
this.Val = val;
}
public TestClass(int val1, int val2)
{
this.Val = val1 + val2;
}
public TestClass(int val1, int val2, int val3, int val4, int val5, int val6, int val7, int val8, int val9, int val10, int val11, int val12, int val13, int val14)
{
this.Val = val1 + val2 + val3 + val4 + val5 + val6 + val7 + val8 + val9 + val10 + val11 + val12 + val13 + val14;
}
}
public static class DynamicFactory
{
private static readonly CallSiteBinder callsiteBinder0 = Binder.InvokeConstructor(
CSharpBinderFlags.None,
typeof(DynamicFactory),
// It is OK to have too many arguments :-)
new CSharpArgumentInfo[]
{
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.IsStaticType | CSharpArgumentInfoFlags.UseCompileTimeType, null), // 0 parameters
});
private static readonly CallSiteBinder callsiteBinder = Binder.InvokeConstructor(
CSharpBinderFlags.None,
typeof(DynamicFactory),
// It is OK to have too many arguments :-)
// Note that this "feature" doesn't work correctly with Mono in the
// case of 0 arguments
new CSharpArgumentInfo[]
{
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.IsStaticType | CSharpArgumentInfoFlags.UseCompileTimeType, null), // 0 parameters
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null), // 1 parameter
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null), // 2 parameters
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null), // 14 parameters
});
// Quirk of Mono with 0 arguments. See callsiteBinder0
private static readonly CallSite<Func<CallSite, Type, object>> CallSite0 = CallSite<Func<CallSite, Type, object>>.Create(callsiteBinder0);
private static readonly CallSite<Func<CallSite, Type, object, object>> CallSite1 = CallSite<Func<CallSite, Type, object, object>>.Create(callsiteBinder);
private static readonly CallSite<Func<CallSite, Type, object, object, object>> CallSite2 = CallSite<Func<CallSite, Type, object, object, object>>.Create(callsiteBinder);
private static readonly CallSite<Func<CallSite, Type, object, object, object, object>> CallSite3 = CallSite<Func<CallSite, Type, object, object, object, object>>.Create(callsiteBinder);
private static readonly CallSite<Func<CallSite, Type, object, object, object, object, object>> CallSite4 = CallSite<Func<CallSite, Type, object, object, object, object, object>>.Create(callsiteBinder);
private static readonly CallSite<Func<CallSite, Type, object, object, object, object, object, object>> CallSite5 = CallSite<Func<CallSite, Type, object, object, object, object, object, object>>.Create(callsiteBinder);
private static readonly CallSite<Func<CallSite, Type, object, object, object, object, object, object, object>> CallSite6 = CallSite<Func<CallSite, Type, object, object, object, object, object, object, object>>.Create(callsiteBinder);
private static readonly CallSite<Func<CallSite, Type, object, object, object, object, object, object, object, object>> CallSite7 = CallSite<Func<CallSite, Type, object, object, object, object, object, object, object, object>>.Create(callsiteBinder);
private static readonly CallSite<Func<CallSite, Type, object, object, object, object, object, object, object, object, object>> CallSite8 = CallSite<Func<CallSite, Type, object, object, object, object, object, object, object, object, object>>.Create(callsiteBinder);
private static readonly CallSite<Func<CallSite, Type, object, object, object, object, object, object, object, object, object, object>> CallSite9 = CallSite<Func<CallSite, Type, object, object, object, object, object, object, object, object, object, object>>.Create(callsiteBinder);
private static readonly CallSite<Func<CallSite, Type, object, object, object, object, object, object, object, object, object, object, object>> CallSite10 = CallSite<Func<CallSite, Type, object, object, object, object, object, object, object, object, object, object, object>>.Create(callsiteBinder);
private static readonly CallSite<Func<CallSite, Type, object, object, object, object, object, object, object, object, object, object, object, object>> CallSite11 = CallSite<Func<CallSite, Type, object, object, object, object, object, object, object, object, object, object, object, object>>.Create(callsiteBinder);
private static readonly CallSite<Func<CallSite, Type, object, object, object, object, object, object, object, object, object, object, object, object, object>> CallSite12 = CallSite<Func<CallSite, Type, object, object, object, object, object, object, object, object, object, object, object, object, object>>.Create(callsiteBinder);
private static readonly CallSite<Func<CallSite, Type, object, object, object, object, object, object, object, object, object, object, object, object, object, object>> CallSite13 = CallSite<Func<CallSite, Type, object, object, object, object, object, object, object, object, object, object, object, object, object, object>>.Create(callsiteBinder);
private static readonly CallSite<Func<CallSite, Type, object, object, object, object, object, object, object, object, object, object, object, object, object, object, object>> CallSite14 = CallSite<Func<CallSite, Type, object, object, object, object, object, object, object, object, object, object, object, object, object, object, object>>.Create(callsiteBinder);
public static object Create(string typeName, params object[] args)
{
return Create(Type.GetType(typeName), args);
}
public static object Create(Type type, params object[] args)
{
if (type == null)
{
throw new ArgumentNullException("type");
}
if (args == null)
{
args = new object[0];
}
object obj;
switch (args.Length)
{
case 0:
// Quirk of Mono with 0 arguments. See callsiteBinder0
obj = CallSite0.Target(CallSite0, type);
break;
case 1:
obj = CallSite1.Target(CallSite1, type, args[0]);
break;
case 2:
obj = CallSite2.Target(CallSite2, type, args[0], args[1]);
break;
case 3:
obj = CallSite3.Target(CallSite3, type, args[0], args[1], args[2]);
break;
case 4:
obj = CallSite4.Target(CallSite4, type, args[0], args[1], args[2], args[3]);
break;
case 5:
obj = CallSite5.Target(CallSite5, type, args[0], args[1], args[2], args[3], args[4]);
break;
case 6:
obj = CallSite6.Target(CallSite6, type, args[0], args[1], args[2], args[3], args[4], args[5]);
break;
case 7:
obj = CallSite7.Target(CallSite7, type, args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
break;
case 8:
obj = CallSite8.Target(CallSite8, type, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]);
break;
case 9:
obj = CallSite9.Target(CallSite9, type, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8]);
break;
case 10:
obj = CallSite10.Target(CallSite10, type, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9]);
break;
case 11:
obj = CallSite11.Target(CallSite11, type, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9], args[10]);
break;
case 12:
obj = CallSite12.Target(CallSite12, type, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9], args[10], args[11]);
break;
case 13:
obj = CallSite13.Target(CallSite13, type, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9], args[10], args[11], args[12]);
break;
case 14:
obj = CallSite14.Target(CallSite14, type, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9], args[10], args[11], args[12], args[13]);
break;
default:
throw new ArgumentException("Too many parameters");
}
return obj;
}
}
public class Program
{
public static void Main()
{
try
{
Type monoRuntime = Type.GetType("Mono.Runtime");
if (monoRuntime != null)
{
System.Reflection.MethodInfo displayName = monoRuntime.GetMethod("GetDisplayName", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
if (displayName != null)
{
Console.WriteLine("Mono version {0}", displayName.Invoke(null, null));
}
}
TestClass tc0 = (TestClass)DynamicFactory.Create("TestClass");
TestClass tc1 = (TestClass)DynamicFactory.Create("TestClass", new ImplicitTest(1.0));
TestClass tc1b = (TestClass)DynamicFactory.Create("TestClass", 1);
TestClass tc2 = (TestClass)DynamicFactory.Create("TestClass", new ImplicitTest(1.0), new ImplicitTest(2.0));
TestClass tc14 = (TestClass)DynamicFactory.Create("TestClass", Enumerable.Range(0, 14).Select(x => new ImplicitTest((double)x)).ToArray());
Console.WriteLine(tc0.Val);
Console.WriteLine(tc1.Val);
Console.WriteLine(tc1b.Val);
Console.WriteLine(tc2.Val);
Console.WriteLine(tc14.Val);
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
}
dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uTGlucTsKdXNpbmcgU3lzdGVtLlJ1bnRpbWUuQ29tcGlsZXJTZXJ2aWNlczsKdXNpbmcgTWljcm9zb2Z0LkNTaGFycC5SdW50aW1lQmluZGVyOyAvLyBSZXF1aXJlcyByZWZlcmVuY2UgdG8gTWljcm9zb2Z0LkNTaGFycAoKcHVibGljIGNsYXNzIEltcGxpY2l0VGVzdAp7CiAgICBwdWJsaWMgZG91YmxlIFZhbCB7IGdldDsgc2V0OyB9CgogICAgcHVibGljIEltcGxpY2l0VGVzdChkb3VibGUgdmFsKQogICAgewogICAgICAgIHRoaXMuVmFsID0gdmFsOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgaW1wbGljaXQgb3BlcmF0b3IgaW50KEltcGxpY2l0VGVzdCBkKQogICAgewogICAgICAgIHJldHVybiAoaW50KWQuVmFsOwogICAgfQp9CgpwdWJsaWMgY2xhc3MgVGVzdENsYXNzCnsKICAgIHB1YmxpYyBpbnQgVmFsIHsgZ2V0OyBzZXQ7IH0KCiAgICBwdWJsaWMgVGVzdENsYXNzKGludCB2YWwgPSA1KQogICAgewogICAgICAgIHRoaXMuVmFsID0gdmFsOwogICAgfQoKICAgIHB1YmxpYyBUZXN0Q2xhc3MoaW50IHZhbDEsIGludCB2YWwyKQogICAgewogICAgICAgIHRoaXMuVmFsID0gdmFsMSArIHZhbDI7CiAgICB9CgogICAgcHVibGljIFRlc3RDbGFzcyhpbnQgdmFsMSwgaW50IHZhbDIsIGludCB2YWwzLCBpbnQgdmFsNCwgaW50IHZhbDUsIGludCB2YWw2LCBpbnQgdmFsNywgaW50IHZhbDgsIGludCB2YWw5LCBpbnQgdmFsMTAsIGludCB2YWwxMSwgaW50IHZhbDEyLCBpbnQgdmFsMTMsIGludCB2YWwxNCkKICAgIHsKICAgICAgICB0aGlzLlZhbCA9IHZhbDEgKyB2YWwyICsgdmFsMyArIHZhbDQgKyB2YWw1ICsgdmFsNiArIHZhbDcgKyB2YWw4ICsgdmFsOSArIHZhbDEwICsgdmFsMTEgKyB2YWwxMiArIHZhbDEzICsgdmFsMTQ7CiAgICB9Cn0KCnB1YmxpYyBzdGF0aWMgY2xhc3MgRHluYW1pY0ZhY3RvcnkKewogICAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgQ2FsbFNpdGVCaW5kZXIgY2FsbHNpdGVCaW5kZXIwID0gQmluZGVyLkludm9rZUNvbnN0cnVjdG9yKAogICAgICAgIENTaGFycEJpbmRlckZsYWdzLk5vbmUsCiAgICAgICAgdHlwZW9mKER5bmFtaWNGYWN0b3J5KSwKICAgICAgICAvLyBJdCBpcyBPSyB0byBoYXZlIHRvbyBtYW55IGFyZ3VtZW50cyA6LSkKICAgICAgICBuZXcgQ1NoYXJwQXJndW1lbnRJbmZvW10gCiAgICAgICAgewogICAgICAgICAgICBDU2hhcnBBcmd1bWVudEluZm8uQ3JlYXRlKENTaGFycEFyZ3VtZW50SW5mb0ZsYWdzLklzU3RhdGljVHlwZSB8IENTaGFycEFyZ3VtZW50SW5mb0ZsYWdzLlVzZUNvbXBpbGVUaW1lVHlwZSwgbnVsbCksIC8vIDAgcGFyYW1ldGVycwogICAgICAgIH0pOwoKICAgIHByaXZhdGUgc3RhdGljIHJlYWRvbmx5IENhbGxTaXRlQmluZGVyIGNhbGxzaXRlQmluZGVyID0gQmluZGVyLkludm9rZUNvbnN0cnVjdG9yKAogICAgICAgIENTaGFycEJpbmRlckZsYWdzLk5vbmUsCiAgICAgICAgdHlwZW9mKER5bmFtaWNGYWN0b3J5KSwKICAgICAgICAvLyBJdCBpcyBPSyB0byBoYXZlIHRvbyBtYW55IGFyZ3VtZW50cyA6LSkKICAgICAgICAvLyBOb3RlIHRoYXQgdGhpcyAiZmVhdHVyZSIgZG9lc24ndCB3b3JrIGNvcnJlY3RseSB3aXRoIE1vbm8gaW4gdGhlCiAgICAgICAgLy8gY2FzZSBvZiAwIGFyZ3VtZW50cwogICAgICAgIG5ldyBDU2hhcnBBcmd1bWVudEluZm9bXSAKICAgICAgICB7CiAgICAgICAgICAgIENTaGFycEFyZ3VtZW50SW5mby5DcmVhdGUoQ1NoYXJwQXJndW1lbnRJbmZvRmxhZ3MuSXNTdGF0aWNUeXBlIHwgQ1NoYXJwQXJndW1lbnRJbmZvRmxhZ3MuVXNlQ29tcGlsZVRpbWVUeXBlLCBudWxsKSwgLy8gMCBwYXJhbWV0ZXJzCiAgICAgICAgICAgIENTaGFycEFyZ3VtZW50SW5mby5DcmVhdGUoQ1NoYXJwQXJndW1lbnRJbmZvRmxhZ3MuTm9uZSwgbnVsbCksIC8vIDEgcGFyYW1ldGVyCiAgICAgICAgICAgIENTaGFycEFyZ3VtZW50SW5mby5DcmVhdGUoQ1NoYXJwQXJndW1lbnRJbmZvRmxhZ3MuTm9uZSwgbnVsbCksIC8vIDIgcGFyYW1ldGVycwogICAgICAgICAgICBDU2hhcnBBcmd1bWVudEluZm8uQ3JlYXRlKENTaGFycEFyZ3VtZW50SW5mb0ZsYWdzLk5vbmUsIG51bGwpLCAKICAgICAgICAgICAgQ1NoYXJwQXJndW1lbnRJbmZvLkNyZWF0ZShDU2hhcnBBcmd1bWVudEluZm9GbGFncy5Ob25lLCBudWxsKSwKICAgICAgICAgICAgQ1NoYXJwQXJndW1lbnRJbmZvLkNyZWF0ZShDU2hhcnBBcmd1bWVudEluZm9GbGFncy5Ob25lLCBudWxsKSwKICAgICAgICAgICAgQ1NoYXJwQXJndW1lbnRJbmZvLkNyZWF0ZShDU2hhcnBBcmd1bWVudEluZm9GbGFncy5Ob25lLCBudWxsKSwgCiAgICAgICAgICAgIENTaGFycEFyZ3VtZW50SW5mby5DcmVhdGUoQ1NoYXJwQXJndW1lbnRJbmZvRmxhZ3MuTm9uZSwgbnVsbCksCiAgICAgICAgICAgIENTaGFycEFyZ3VtZW50SW5mby5DcmVhdGUoQ1NoYXJwQXJndW1lbnRJbmZvRmxhZ3MuTm9uZSwgbnVsbCksCiAgICAgICAgICAgIENTaGFycEFyZ3VtZW50SW5mby5DcmVhdGUoQ1NoYXJwQXJndW1lbnRJbmZvRmxhZ3MuTm9uZSwgbnVsbCksIAogICAgICAgICAgICBDU2hhcnBBcmd1bWVudEluZm8uQ3JlYXRlKENTaGFycEFyZ3VtZW50SW5mb0ZsYWdzLk5vbmUsIG51bGwpLAogICAgICAgICAgICBDU2hhcnBBcmd1bWVudEluZm8uQ3JlYXRlKENTaGFycEFyZ3VtZW50SW5mb0ZsYWdzLk5vbmUsIG51bGwpLAogICAgICAgICAgICBDU2hhcnBBcmd1bWVudEluZm8uQ3JlYXRlKENTaGFycEFyZ3VtZW50SW5mb0ZsYWdzLk5vbmUsIG51bGwpLAogICAgICAgICAgICBDU2hhcnBBcmd1bWVudEluZm8uQ3JlYXRlKENTaGFycEFyZ3VtZW50SW5mb0ZsYWdzLk5vbmUsIG51bGwpLAogICAgICAgICAgICBDU2hhcnBBcmd1bWVudEluZm8uQ3JlYXRlKENTaGFycEFyZ3VtZW50SW5mb0ZsYWdzLk5vbmUsIG51bGwpLCAvLyAxNCBwYXJhbWV0ZXJzCiAgICAgICAgfSk7CgogICAgLy8gUXVpcmsgb2YgTW9ubyB3aXRoIDAgYXJndW1lbnRzLiBTZWUgY2FsbHNpdGVCaW5kZXIwCiAgICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBDYWxsU2l0ZTxGdW5jPENhbGxTaXRlLCBUeXBlLCBvYmplY3Q+PiBDYWxsU2l0ZTAgPSBDYWxsU2l0ZTxGdW5jPENhbGxTaXRlLCBUeXBlLCBvYmplY3Q+Pi5DcmVhdGUoY2FsbHNpdGVCaW5kZXIwKTsKICAgIAogICAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgQ2FsbFNpdGU8RnVuYzxDYWxsU2l0ZSwgVHlwZSwgb2JqZWN0LCBvYmplY3Q+PiBDYWxsU2l0ZTEgPSBDYWxsU2l0ZTxGdW5jPENhbGxTaXRlLCBUeXBlLCBvYmplY3QsIG9iamVjdD4+LkNyZWF0ZShjYWxsc2l0ZUJpbmRlcik7CiAgICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBDYWxsU2l0ZTxGdW5jPENhbGxTaXRlLCBUeXBlLCBvYmplY3QsIG9iamVjdCwgb2JqZWN0Pj4gQ2FsbFNpdGUyID0gQ2FsbFNpdGU8RnVuYzxDYWxsU2l0ZSwgVHlwZSwgb2JqZWN0LCBvYmplY3QsIG9iamVjdD4+LkNyZWF0ZShjYWxsc2l0ZUJpbmRlcik7CiAgICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBDYWxsU2l0ZTxGdW5jPENhbGxTaXRlLCBUeXBlLCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3Q+PiBDYWxsU2l0ZTMgPSBDYWxsU2l0ZTxGdW5jPENhbGxTaXRlLCBUeXBlLCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3Q+Pi5DcmVhdGUoY2FsbHNpdGVCaW5kZXIpOwogICAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgQ2FsbFNpdGU8RnVuYzxDYWxsU2l0ZSwgVHlwZSwgb2JqZWN0LCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3Q+PiBDYWxsU2l0ZTQgPSBDYWxsU2l0ZTxGdW5jPENhbGxTaXRlLCBUeXBlLCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3QsIG9iamVjdD4+LkNyZWF0ZShjYWxsc2l0ZUJpbmRlcik7CiAgICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBDYWxsU2l0ZTxGdW5jPENhbGxTaXRlLCBUeXBlLCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3QsIG9iamVjdCwgb2JqZWN0Pj4gQ2FsbFNpdGU1ID0gQ2FsbFNpdGU8RnVuYzxDYWxsU2l0ZSwgVHlwZSwgb2JqZWN0LCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3QsIG9iamVjdD4+LkNyZWF0ZShjYWxsc2l0ZUJpbmRlcik7CiAgICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBDYWxsU2l0ZTxGdW5jPENhbGxTaXRlLCBUeXBlLCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3Q+PiBDYWxsU2l0ZTYgPSBDYWxsU2l0ZTxGdW5jPENhbGxTaXRlLCBUeXBlLCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3Q+Pi5DcmVhdGUoY2FsbHNpdGVCaW5kZXIpOwogICAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgQ2FsbFNpdGU8RnVuYzxDYWxsU2l0ZSwgVHlwZSwgb2JqZWN0LCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3Q+PiBDYWxsU2l0ZTcgPSBDYWxsU2l0ZTxGdW5jPENhbGxTaXRlLCBUeXBlLCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3QsIG9iamVjdD4+LkNyZWF0ZShjYWxsc2l0ZUJpbmRlcik7CiAgICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBDYWxsU2l0ZTxGdW5jPENhbGxTaXRlLCBUeXBlLCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3QsIG9iamVjdCwgb2JqZWN0Pj4gQ2FsbFNpdGU4ID0gQ2FsbFNpdGU8RnVuYzxDYWxsU2l0ZSwgVHlwZSwgb2JqZWN0LCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3QsIG9iamVjdD4+LkNyZWF0ZShjYWxsc2l0ZUJpbmRlcik7CiAgICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBDYWxsU2l0ZTxGdW5jPENhbGxTaXRlLCBUeXBlLCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3Q+PiBDYWxsU2l0ZTkgPSBDYWxsU2l0ZTxGdW5jPENhbGxTaXRlLCBUeXBlLCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3Q+Pi5DcmVhdGUoY2FsbHNpdGVCaW5kZXIpOwogICAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgQ2FsbFNpdGU8RnVuYzxDYWxsU2l0ZSwgVHlwZSwgb2JqZWN0LCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3Q+PiBDYWxsU2l0ZTEwID0gQ2FsbFNpdGU8RnVuYzxDYWxsU2l0ZSwgVHlwZSwgb2JqZWN0LCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3Q+Pi5DcmVhdGUoY2FsbHNpdGVCaW5kZXIpOwogICAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgQ2FsbFNpdGU8RnVuYzxDYWxsU2l0ZSwgVHlwZSwgb2JqZWN0LCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3QsIG9iamVjdD4+IENhbGxTaXRlMTEgPSBDYWxsU2l0ZTxGdW5jPENhbGxTaXRlLCBUeXBlLCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3QsIG9iamVjdCwgb2JqZWN0Pj4uQ3JlYXRlKGNhbGxzaXRlQmluZGVyKTsKICAgIHByaXZhdGUgc3RhdGljIHJlYWRvbmx5IENhbGxTaXRlPEZ1bmM8Q2FsbFNpdGUsIFR5cGUsIG9iamVjdCwgb2JqZWN0LCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3QsIG9iamVjdD4+IENhbGxTaXRlMTIgPSBDYWxsU2l0ZTxGdW5jPENhbGxTaXRlLCBUeXBlLCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3Q+Pi5DcmVhdGUoY2FsbHNpdGVCaW5kZXIpOwogICAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgQ2FsbFNpdGU8RnVuYzxDYWxsU2l0ZSwgVHlwZSwgb2JqZWN0LCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3Q+PiBDYWxsU2l0ZTEzID0gQ2FsbFNpdGU8RnVuYzxDYWxsU2l0ZSwgVHlwZSwgb2JqZWN0LCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3Q+Pi5DcmVhdGUoY2FsbHNpdGVCaW5kZXIpOwogICAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgQ2FsbFNpdGU8RnVuYzxDYWxsU2l0ZSwgVHlwZSwgb2JqZWN0LCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3QsIG9iamVjdD4+IENhbGxTaXRlMTQgPSBDYWxsU2l0ZTxGdW5jPENhbGxTaXRlLCBUeXBlLCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3QsIG9iamVjdCwgb2JqZWN0LCBvYmplY3QsIG9iamVjdCwgb2JqZWN0Pj4uQ3JlYXRlKGNhbGxzaXRlQmluZGVyKTsKCiAgICBwdWJsaWMgc3RhdGljIG9iamVjdCBDcmVhdGUoc3RyaW5nIHR5cGVOYW1lLCBwYXJhbXMgb2JqZWN0W10gYXJncykKICAgIHsKICAgICAgICByZXR1cm4gQ3JlYXRlKFR5cGUuR2V0VHlwZSh0eXBlTmFtZSksIGFyZ3MpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgb2JqZWN0IENyZWF0ZShUeXBlIHR5cGUsIHBhcmFtcyBvYmplY3RbXSBhcmdzKQogICAgewogICAgICAgIGlmICh0eXBlID09IG51bGwpCiAgICAgICAgewogICAgICAgICAgICB0aHJvdyBuZXcgQXJndW1lbnROdWxsRXhjZXB0aW9uKCJ0eXBlIik7CiAgICAgICAgfQoKICAgICAgICBpZiAoYXJncyA9PSBudWxsKQogICAgICAgIHsKICAgICAgICAgICAgYXJncyA9IG5ldyBvYmplY3RbMF07CiAgICAgICAgfQoKICAgICAgICBvYmplY3Qgb2JqOwoKICAgICAgICBzd2l0Y2ggKGFyZ3MuTGVuZ3RoKQogICAgICAgIHsKICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgLy8gUXVpcmsgb2YgTW9ubyB3aXRoIDAgYXJndW1lbnRzLiBTZWUgY2FsbHNpdGVCaW5kZXIwCiAgICAgICAgICAgICAgICBvYmogPSBDYWxsU2l0ZTAuVGFyZ2V0KENhbGxTaXRlMCwgdHlwZSk7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgICAgIG9iaiA9IENhbGxTaXRlMS5UYXJnZXQoQ2FsbFNpdGUxLCB0eXBlLCBhcmdzWzBdKTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSAyOgogICAgICAgICAgICAgICAgb2JqID0gQ2FsbFNpdGUyLlRhcmdldChDYWxsU2l0ZTIsIHR5cGUsIGFyZ3NbMF0sIGFyZ3NbMV0pOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIDM6CiAgICAgICAgICAgICAgICBvYmogPSBDYWxsU2l0ZTMuVGFyZ2V0KENhbGxTaXRlMywgdHlwZSwgYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSk7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgNDoKICAgICAgICAgICAgICAgIG9iaiA9IENhbGxTaXRlNC5UYXJnZXQoQ2FsbFNpdGU0LCB0eXBlLCBhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdLCBhcmdzWzNdKTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSA1OgogICAgICAgICAgICAgICAgb2JqID0gQ2FsbFNpdGU1LlRhcmdldChDYWxsU2l0ZTUsIHR5cGUsIGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0sIGFyZ3NbM10sIGFyZ3NbNF0pOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIDY6CiAgICAgICAgICAgICAgICBvYmogPSBDYWxsU2l0ZTYuVGFyZ2V0KENhbGxTaXRlNiwgdHlwZSwgYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSwgYXJnc1szXSwgYXJnc1s0XSwgYXJnc1s1XSk7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgNzoKICAgICAgICAgICAgICAgIG9iaiA9IENhbGxTaXRlNy5UYXJnZXQoQ2FsbFNpdGU3LCB0eXBlLCBhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdLCBhcmdzWzNdLCBhcmdzWzRdLCBhcmdzWzVdLCBhcmdzWzZdKTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSA4OgogICAgICAgICAgICAgICAgb2JqID0gQ2FsbFNpdGU4LlRhcmdldChDYWxsU2l0ZTgsIHR5cGUsIGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0sIGFyZ3NbM10sIGFyZ3NbNF0sIGFyZ3NbNV0sIGFyZ3NbNl0sIGFyZ3NbN10pOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIDk6CiAgICAgICAgICAgICAgICBvYmogPSBDYWxsU2l0ZTkuVGFyZ2V0KENhbGxTaXRlOSwgdHlwZSwgYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSwgYXJnc1szXSwgYXJnc1s0XSwgYXJnc1s1XSwgYXJnc1s2XSwgYXJnc1s3XSwgYXJnc1s4XSk7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgMTA6CiAgICAgICAgICAgICAgICBvYmogPSBDYWxsU2l0ZTEwLlRhcmdldChDYWxsU2l0ZTEwLCB0eXBlLCBhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdLCBhcmdzWzNdLCBhcmdzWzRdLCBhcmdzWzVdLCBhcmdzWzZdLCBhcmdzWzddLCBhcmdzWzhdLCBhcmdzWzldKTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSAxMToKICAgICAgICAgICAgICAgIG9iaiA9IENhbGxTaXRlMTEuVGFyZ2V0KENhbGxTaXRlMTEsIHR5cGUsIGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0sIGFyZ3NbM10sIGFyZ3NbNF0sIGFyZ3NbNV0sIGFyZ3NbNl0sIGFyZ3NbN10sIGFyZ3NbOF0sIGFyZ3NbOV0sIGFyZ3NbMTBdKTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSAxMjoKICAgICAgICAgICAgICAgIG9iaiA9IENhbGxTaXRlMTIuVGFyZ2V0KENhbGxTaXRlMTIsIHR5cGUsIGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0sIGFyZ3NbM10sIGFyZ3NbNF0sIGFyZ3NbNV0sIGFyZ3NbNl0sIGFyZ3NbN10sIGFyZ3NbOF0sIGFyZ3NbOV0sIGFyZ3NbMTBdLCBhcmdzWzExXSk7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgMTM6CiAgICAgICAgICAgICAgICBvYmogPSBDYWxsU2l0ZTEzLlRhcmdldChDYWxsU2l0ZTEzLCB0eXBlLCBhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdLCBhcmdzWzNdLCBhcmdzWzRdLCBhcmdzWzVdLCBhcmdzWzZdLCBhcmdzWzddLCBhcmdzWzhdLCBhcmdzWzldLCBhcmdzWzEwXSwgYXJnc1sxMV0sIGFyZ3NbMTJdKTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSAxNDoKICAgICAgICAgICAgICAgIG9iaiA9IENhbGxTaXRlMTQuVGFyZ2V0KENhbGxTaXRlMTQsIHR5cGUsIGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0sIGFyZ3NbM10sIGFyZ3NbNF0sIGFyZ3NbNV0sIGFyZ3NbNl0sIGFyZ3NbN10sIGFyZ3NbOF0sIGFyZ3NbOV0sIGFyZ3NbMTBdLCBhcmdzWzExXSwgYXJnc1sxMl0sIGFyZ3NbMTNdKTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIHRocm93IG5ldyBBcmd1bWVudEV4Y2VwdGlvbigiVG9vIG1hbnkgcGFyYW1ldGVycyIpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIG9iajsKICAgIH0KfQoKcHVibGljIGNsYXNzIFByb2dyYW0KewogICAgcHVibGljIHN0YXRpYyB2b2lkIE1haW4oKQogICAgewogICAgCXRyeQogICAgCXsKICAgIAkJVHlwZSBtb25vUnVudGltZSA9IFR5cGUuR2V0VHlwZSgiTW9uby5SdW50aW1lIik7CiAgICAJCQoJCQlpZiAobW9ub1J1bnRpbWUgIT0gbnVsbCkKCQkJewoJCQkgICAgU3lzdGVtLlJlZmxlY3Rpb24uTWV0aG9kSW5mbyBkaXNwbGF5TmFtZSA9IG1vbm9SdW50aW1lLkdldE1ldGhvZCgiR2V0RGlzcGxheU5hbWUiLCBTeXN0ZW0uUmVmbGVjdGlvbi5CaW5kaW5nRmxhZ3MuTm9uUHVibGljIHwgU3lzdGVtLlJlZmxlY3Rpb24uQmluZGluZ0ZsYWdzLlN0YXRpYyk7CgkJCSAgICAKCQkJICAgIGlmIChkaXNwbGF5TmFtZSAhPSBudWxsKQoJCQkgICAgewoJCQkgICAgICAgIENvbnNvbGUuV3JpdGVMaW5lKCJNb25vIHZlcnNpb24gezB9IiwgZGlzcGxheU5hbWUuSW52b2tlKG51bGwsIG51bGwpKTsKCQkJICAgIH0KCQkJfQoKCSAgICAgICAgVGVzdENsYXNzIHRjMCA9IChUZXN0Q2xhc3MpRHluYW1pY0ZhY3RvcnkuQ3JlYXRlKCJUZXN0Q2xhc3MiKTsKCSAgICAgICAgVGVzdENsYXNzIHRjMSA9IChUZXN0Q2xhc3MpRHluYW1pY0ZhY3RvcnkuQ3JlYXRlKCJUZXN0Q2xhc3MiLCBuZXcgSW1wbGljaXRUZXN0KDEuMCkpOwoJICAgICAgICBUZXN0Q2xhc3MgdGMxYiA9IChUZXN0Q2xhc3MpRHluYW1pY0ZhY3RvcnkuQ3JlYXRlKCJUZXN0Q2xhc3MiLCAxKTsKCSAgICAgICAgVGVzdENsYXNzIHRjMiA9IChUZXN0Q2xhc3MpRHluYW1pY0ZhY3RvcnkuQ3JlYXRlKCJUZXN0Q2xhc3MiLCBuZXcgSW1wbGljaXRUZXN0KDEuMCksIG5ldyBJbXBsaWNpdFRlc3QoMi4wKSk7CgkgICAgICAgIFRlc3RDbGFzcyB0YzE0ID0gKFRlc3RDbGFzcylEeW5hbWljRmFjdG9yeS5DcmVhdGUoIlRlc3RDbGFzcyIsIEVudW1lcmFibGUuUmFuZ2UoMCwgMTQpLlNlbGVjdCh4ID0+IG5ldyBJbXBsaWNpdFRlc3QoKGRvdWJsZSl4KSkuVG9BcnJheSgpKTsKCQoJICAgICAgICBDb25zb2xlLldyaXRlTGluZSh0YzAuVmFsKTsKCSAgICAgICAgQ29uc29sZS5Xcml0ZUxpbmUodGMxLlZhbCk7CgkgICAgICAgIENvbnNvbGUuV3JpdGVMaW5lKHRjMWIuVmFsKTsKCSAgICAgICAgQ29uc29sZS5Xcml0ZUxpbmUodGMyLlZhbCk7CgkgICAgICAgIENvbnNvbGUuV3JpdGVMaW5lKHRjMTQuVmFsKTsKICAgIAl9CiAgICAJY2F0Y2ggKEV4Y2VwdGlvbiBleCkKICAgIAl7CiAgICAJCUNvbnNvbGUuV3JpdGVMaW5lKGV4KTsKICAgIAl9CiAgICB9Cn0=